|
| 1 | +## Django MVC(MTV)目录结构 |
| 2 | + |
| 3 | +```bash |
| 4 | +django-order/ |
| 5 | +├── manage.py # 项目管理入口脚本,启动 Django 服务 |
| 6 | +├── requirements.txt # 项目依赖列表 |
| 7 | +├── config/ # 全局配置模块 |
| 8 | +│ ├── __init__.py |
| 9 | +│ ├── settings/ # 分环境的配置(基础、开发、生产等) |
| 10 | +│ │ ├── __init__.py |
| 11 | +│ │ ├── base.py # 公共基础配置 |
| 12 | +│ │ ├── development.py # 开发环境配置 |
| 13 | +│ │ └── production.py # 生产环境配置 |
| 14 | +│ ├── urls.py # 全局 URL 配置,统一路由入口 |
| 15 | +│ ├── wsgi.py # WSGI 应用,用于部署 |
| 16 | +│ └── asgi.py # ASGI 应用,支持异步 |
| 17 | +├── apps/ # 应用(模块)目录 |
| 18 | +│ └── order/ # Order 应用(示例模块) |
| 19 | +│ ├── __init__.py |
| 20 | +│ ├── admin.py # Django Admin 后台注册 |
| 21 | +│ ├── apps.py # 应用配置类 |
| 22 | +│ ├── models.py # 数据模型定义(订单模型) |
| 23 | +│ ├── views.py # 视图层(处理请求、执行业务逻辑并返回响应) |
| 24 | +│ ├── urls.py # 应用内部 URL 路由配置 |
| 25 | +│ ├── forms.py # 表单定义,用于数据验证和处理 |
| 26 | +│ ├── serializers.py # 序列化器(如使用 Django REST Framework) |
| 27 | +│ ├── tests/ # 单元测试目录 |
| 28 | +│ │ ├── __init__.py |
| 29 | +│ │ └── test_views.py |
| 30 | +│ ├── migrations/ # 数据库迁移记录 |
| 31 | +│ │ └── __init__.py |
| 32 | +│ └── templates/ # 应用模板文件(用于渲染 HTML) |
| 33 | +│ └── order/ # Order 应用专用模板 |
| 34 | +│ └── order_detail.html |
| 35 | +├── static/ # 静态资源(CSS、JS、图片等) |
| 36 | +│ └── order/ # Order 应用专用静态文件 |
| 37 | +│ ├── css/ |
| 38 | +│ ├── js/ |
| 39 | +│ └── images/ |
| 40 | +└── docs/ # 项目文档 |
| 41 | +``` |
| 42 | + |
| 43 | + |
| 44 | +## 目录结构说明 |
| 45 | +### manage.py |
| 46 | +Django 的命令行工具,用于项目管理、数据库迁移、启动开发服务器等任务。 |
| 47 | + |
| 48 | +### requirements.txt |
| 49 | +列出了项目所需的所有 Python 包,便于环境搭建和依赖管理。 |
| 50 | + |
| 51 | +### config/ |
| 52 | +包含全局配置文件: |
| 53 | + - settings/:分环境的配置,通常将公共基础配置与各环境(开发、生产)特有配置分离。 |
| 54 | + - urls.py:全局路由文件,集中管理 URL 分发。 |
| 55 | + - wsgi.py/asgi.py:部署时使用的 WSGI/ASGI 应用入口。 |
| 56 | + |
| 57 | +### apps/ |
| 58 | +按功能划分的 Django 应用(模块),每个应用独立实现业务逻辑: |
| 59 | + - order/:订单模块,内部包含模型(models.py)、视图(views.py)、路由(urls.py)、表单(forms.py)、测试(tests/)、模板(templates/)等。 |
| 60 | + - 这种分层结构符合 Django 的 MTV 架构理念,其中 View(视图)承担了 Controller 的角色,模板(Template)负责呈现数据,模型(Model)封装数据结构和业务逻辑。 |
| 61 | + |
| 62 | +### static/ |
| 63 | +存放项目的静态资源,如 CSS、JavaScript、图片等,支持前后端分离或模板渲染时的静态资源加载。 |
| 64 | + |
| 65 | + |
| 66 | +## 运行项目 |
| 67 | +假设已正确配置数据库与环境变量。 |
| 68 | +```bash |
| 69 | +# 安装依赖 |
| 70 | +$ pip install -r requirements.txt |
| 71 | + |
| 72 | +# 启动开发服务器 |
| 73 | +$ python manage.py runserver |
| 74 | + |
| 75 | +# 访问接口 |
| 76 | +$ curl http://localhost:8000/api/orders/1 |
| 77 | +$ curl -X POST http://localhost:8000/api/orders -d "order_no=20240501" |
| 78 | + |
| 79 | +# 运行测试 |
| 80 | +$ python manage.py test apps.order |
| 81 | +``` |
| 82 | + |
| 83 | +## Django 采用 MTV 架构 |
| 84 | +借鉴了传统 MVC 模型,主要分为以下: |
| 85 | +```text |
| 86 | +Model(数据模型) → Template(模板层) → View(视图/控制器) |
| 87 | +``` |
| 88 | +- Model:负责定义数据结构和业务逻辑,使用 Django ORM 与数据库交互。 |
| 89 | +- Template:负责呈现数据,生成 HTML 页面。 |
| 90 | +- View:负责处理请求、执行业务逻辑并返回响应,相当于传统 MVC 中的 Controller。 |
| 91 | + |
| 92 | +### 分层代码 |
| 93 | + |
| 94 | +- **路由配置(Router)** |
| 95 | +将视图函数与 URL 路径进行绑定,实现请求的分发。 |
| 96 | +```python |
| 97 | +# apps/order/urls.py |
| 98 | +from django.urls import path |
| 99 | +from . import views |
| 100 | + |
| 101 | +urlpatterns = [ |
| 102 | + path('<int:id>/', views.order_detail, name='order_detail'), |
| 103 | + path('create/', views.order_create, name='order_create'), |
| 104 | +] |
| 105 | +``` |
| 106 | +在全局路由中引入各应用的路由配置: |
| 107 | +```python |
| 108 | +# config/urls.py |
| 109 | +from django.contrib import admin |
| 110 | +from django.urls import path, include |
| 111 | + |
| 112 | +urlpatterns = [ |
| 113 | + path('admin/', admin.site.urls), |
| 114 | + path('order/', include('apps.order.urls')), # 将 Order 应用的路由包含进来 |
| 115 | +] |
| 116 | +``` |
| 117 | + |
| 118 | +- **视图层(View)视图层** |
| 119 | +处理HTTP请求,类似Controller |
| 120 | +```python |
| 121 | +# apps/order/views.py |
| 122 | +from django.http import JsonResponse |
| 123 | +from django.views import View |
| 124 | +from .services import OrderService |
| 125 | +from utils.response import api_response |
| 126 | + |
| 127 | +class OrderAPI(View): |
| 128 | + def get(self, request, order_id): |
| 129 | + order = OrderService.get_order_by_id(order_id) |
| 130 | + return api_response(data=order.to_dict()) |
| 131 | + |
| 132 | + def post(self, request): |
| 133 | + data = request.POST.dict() |
| 134 | + order = OrderService.create_order(data) |
| 135 | + return api_response(data=order.to_dict(), status=201) |
| 136 | +``` |
| 137 | + |
| 138 | +- **服务层(Service)** |
| 139 | +```python |
| 140 | +# apps/order/services.py |
| 141 | +from .models import Order |
| 142 | + |
| 143 | +class OrderService: |
| 144 | + @staticmethod |
| 145 | + def get_order_by_id(order_id: int) -> Order: |
| 146 | + try: |
| 147 | + return Order.objects.get(id=order_id) |
| 148 | + except Order.DoesNotExist: |
| 149 | + raise OrderNotFoundError(f"Order {order_id} not found") |
| 150 | + |
| 151 | + @staticmethod |
| 152 | + def create_order(order_data: dict) -> Order: |
| 153 | + return Order.objects.create(**order_data) |
| 154 | +``` |
| 155 | + |
| 156 | +- **自定义 Manager(类似 Repository 模式)** |
| 157 | +```python |
| 158 | +# apps/order/managers.py |
| 159 | +from django.db import models |
| 160 | + |
| 161 | +class OrderManager(models.Manager): |
| 162 | + def create_order(self, order_no, user, **kwargs): |
| 163 | + """创建订单(带业务校验)""" |
| 164 | + if self.filter(order_no=order_no).exists(): |
| 165 | + raise ValueError("订单号已存在") |
| 166 | + return self.create(order_no=order_no, user=user, **kwargs) |
| 167 | + |
| 168 | + def get_large_orders(self, min_amount=1000): |
| 169 | + """查询大额订单""" |
| 170 | + return self.filter(amount__gte=min_amount).prefetch_related('items') |
| 171 | + |
| 172 | +# 在 Model 中使用 |
| 173 | +class Order(models.Model): |
| 174 | + objects = OrderManager() # 替换默认 Manager |
| 175 | + # ... 其他字段 ... |
| 176 | +``` |
| 177 | + |
| 178 | +- **模型层(Model)** |
| 179 | +```python |
| 180 | +# apps/order/models.py |
| 181 | +from django.db import models |
| 182 | + |
| 183 | +class Order(models.Model): |
| 184 | + order_no = models.CharField(max_length=50, unique=True) |
| 185 | + user_id = models.PositiveIntegerField(db_index=True) |
| 186 | + order_name = models.CharField(max_length=255) |
| 187 | + amount = models.DecimalField(max_digits=10, decimal_places=2) |
| 188 | + status = models.CharField(max_length=50) |
| 189 | + created_at = models.DateTimeField(auto_now_add=True) |
| 190 | + updated_at = models.DateTimeField(auto_now=True) |
| 191 | + |
| 192 | + class Meta: |
| 193 | + db_table = 'orders' |
| 194 | + ordering = ['-created_at'] |
| 195 | + |
| 196 | + def __str__(self): |
| 197 | + return f'Order {self.order_no}' |
| 198 | +``` |
| 199 | + |
| 200 | +## 最佳实践 |
| 201 | +### 中间件配置 |
| 202 | +```python |
| 203 | +# utils/middleware/logging.py |
| 204 | +class LoggingMiddleware: |
| 205 | + def __init__(self, get_response): |
| 206 | + self.get_response = get_response |
| 207 | + |
| 208 | + def __call__(self, request): |
| 209 | + print(f"[{request.method}] {request.path}") |
| 210 | + response = self.get_response(request) |
| 211 | + return response |
| 212 | + |
| 213 | +# config/settings.py |
| 214 | +MIDDLEWARE = [ |
| 215 | + 'utils.middleware.logging.LoggingMiddleware', |
| 216 | + # ... |
| 217 | +] |
| 218 | +``` |
| 219 | + |
| 220 | +### 统一响应格式 |
| 221 | +```python |
| 222 | +# utils/response.py |
| 223 | +from django.http import JsonResponse |
| 224 | + |
| 225 | +def api_response(data=None, message='success', status=200): |
| 226 | + return JsonResponse({ |
| 227 | + 'code': 0 if status < 400 else 1, |
| 228 | + 'message': message, |
| 229 | + 'data': data |
| 230 | + }, status=status) |
| 231 | +``` |
| 232 | + |
| 233 | +### 接口隔离(Repository模式) |
| 234 | + |
| 235 | +```python |
| 236 | +# apps/order/repositories.py(可选) |
| 237 | +class OrderRepository: |
| 238 | + @classmethod |
| 239 | + def find_by_status(cls, status: str): |
| 240 | + return Order.objects.filter(status=status) |
| 241 | +``` |
| 242 | + |
| 243 | +### 数据库迁移 |
| 244 | +```python |
| 245 | +# 生成迁移文件 |
| 246 | +$ python manage.py makemigrations order |
| 247 | + |
| 248 | +# 执行迁移 |
| 249 | +$ python manage.py migrate |
| 250 | +``` |
| 251 | + |
| 252 | +## 最佳实践总结 |
| 253 | +### 严格分层 |
| 254 | + - views.py 仅处理 HTTP 请求解析和响应 |
| 255 | + - 业务逻辑集中在 services.py |
| 256 | + - 数据操作通过 Model 的 objects Manager 或自定义 Repository |
| 257 | + |
| 258 | +## 事务管理 |
| 259 | +- 使用装饰器管理事务 |
| 260 | +```python |
| 261 | +from django.db import transaction |
| 262 | + |
| 263 | +@transaction.atomic |
| 264 | +def create_order_with_items(order_data, items_data): |
| 265 | + order = Order.objects.create(**order_data) |
| 266 | + for item in items_data: |
| 267 | + OrderItem.objects.create(order=order, **item) |
| 268 | + return order |
| 269 | +``` |
| 270 | + |
| 271 | +### 上下文管理器 |
| 272 | +```python |
| 273 | +def update_order_status(order_id, new_status): |
| 274 | + try: |
| 275 | + with transaction.atomic(): |
| 276 | + order = Order.objects.select_for_update().get(id=order_id) |
| 277 | + order.status = new_status |
| 278 | + order.save() |
| 279 | + # 其他关联操作... |
| 280 | + except Order.DoesNotExist: |
| 281 | + handle_error() |
| 282 | +``` |
| 283 | + |
| 284 | +### DRY 原则 |
| 285 | + - 复用通用组件(如 api_response) |
| 286 | + - 使用 Django 的 class-based views 减少重复代码 |
| 287 | + |
| 288 | +### 安全增强 |
| 289 | + |
| 290 | +```python |
| 291 | +# 防止 SQL 注入 |
| 292 | +Order.objects.raw('SELECT * FROM orders WHERE id = %s', [order_id]) |
| 293 | + |
| 294 | +# CSRF 保护(默认启用) |
| 295 | +@csrf_exempt # 谨慎使用 |
| 296 | +class OrderAPI(View): ... |
| 297 | +``` |
| 298 | + |
| 299 | +### 性能优化 |
| 300 | + |
| 301 | +```python |
| 302 | +# 使用 select_related/prefetch_related 减少查询 |
| 303 | +Order.objects.select_related('user').filter(status='pending') |
| 304 | + |
| 305 | +# 添加数据库索引 |
| 306 | +class Order(models.Model): |
| 307 | + user_id = models.PositiveIntegerField(db_index=True) |
| 308 | +``` |
| 309 | + |
| 310 | +### 测试覆盖 |
| 311 | + |
| 312 | +```python |
| 313 | +# apps/order/tests.py |
| 314 | +from django.test import TestCase |
| 315 | +from .models import Order |
| 316 | + |
| 317 | +class OrderTestCase(TestCase): |
| 318 | + def test_order_creation(self): |
| 319 | + order = Order.objects.create(order_no='TEST123') |
| 320 | + self.assertEqual(order.status, 'pending') |
| 321 | +``` |
| 322 | + |
| 323 | +## Django 架构优势 |
| 324 | +### 全栈能力 |
| 325 | +- 内置 ORM、Admin、模板引擎,适合快速开发全栈应用 |
| 326 | + |
| 327 | +### 高扩展性 |
| 328 | +- 通过中间件、信号机制灵活扩展功能 |
| 329 | + |
| 330 | +### 生态丰富 |
| 331 | +- 可集成 Django REST framework 构建 API |
| 332 | +- 支持 Celery 处理异步任务 |
| 333 | + |
| 334 | +### 企业级安全 |
| 335 | +- 默认提供 CSRF、XSS、SQL 注入防护 |
| 336 | + |
| 337 | +通过此结构,Django 可实现清晰的 MTV 分层,同时保持开发效率与代码可维护性。 |
| 338 | + |
| 339 | +## 总结 |
| 340 | +1. **高度集成**:内置强大的 ORM、模板系统、认证和管理后台,极大地提高了开发效率。 |
| 341 | +2. **明确分层**:通过分离 Model、Template 和 View,实现关注点分离,使得代码易于维护和扩展。 |
| 342 | +3. **丰富生态**:拥有大量第三方库和插件,能够满足各种业务需求,并与其他系统轻松集成。 |
| 343 | +4. **社区支持强大**:成熟的文档和活跃的社区使得问题解决和技术支持更加便捷。 |
| 344 | + |
0 commit comments