Django项目架构
背景:很多人写 Django 时容易“什么都往 views 里塞”,结果项目一大就乱套了。
需要把 视图层 / 业务层 / 数据层 等职责清晰分出来。
图解说明
-
Client:浏览器 / App / 前端调用 API。
-
urls.py:定义 API 路由,把请求分发到对应的 ViewSet。
-
views.py:控制器层(类似 Spring Controller),只负责调度。
-
serializers.py:数据输入/输出格式化 & 校验(类似 DTO/Validator)。
-
services.py:业务逻辑核心(类似 Service)。
-
models.py:数据库 ORM(类似 Repository/DAO)。
-
tasks.py:异步任务(Celery/RQ 等),做发邮件/推送等耗时操作。
-
permissions.py:权限认证、用户访问控制。
-
utils.py:通用工具函数。
-
Database:最终的数据存储。
下面是详细的介绍
一、Django 的天然 MVC / MTV 结构
Django 官方称之为 MTV 模式,其实和 Spring MVC 的思想一致,只是命名不同:
-
Model(模型) → 数据层
- 定义数据库表(ORM)
- 封装业务数据对象
- 数据校验(字段约束)
-
Template(模板) → 表现层
- 前端渲染 HTML 的模板(如果是纯 API 项目,模板层弱化)
-
View(视图) → 控制层
- 接收请求、调用业务逻辑、返回响应(JSON/HTML)
不过在实际开发中,Django 的 View 很容易变肥,所以我们需要借鉴 Spring MVC 的 Service/Controller 分层思想,进行更合理的拆分。
二、推荐的 Django 分层逻辑
1. models.py(数据模型层)
- 定义数据库结构(ORM)
- 约束字段规则(null、unique、default 等)
- 封装一些跟数据紧密相关的方法(例如
User.objects.active_users()
)
👉 注意:不要在 model 里写复杂的业务逻辑,它应该只管数据。
2. serializers.py(数据序列化 & 校验层)
-
类似 Spring 里的 DTO + Validator
-
负责:
- 数据的输入/输出转换(JSON ↔ Python 对象)
- 字段级/对象级校验
- 定义 API 数据格式
👉 业务逻辑不要放这里,它只管“数据是否合法、怎么展示”。
3. views.py / api.py(控制器层)
-
类似 Spring 的 Controller
-
负责:
- 接收 HTTP 请求
- 调用 Service 层 处理逻辑
- 返回响应(Response/JsonResponse)
👉 只做 调度,不做业务。保持尽量轻量。
4. services.py(业务逻辑层,推荐新增)
-
类似 Spring 的 Service
-
封装核心业务逻辑,便于复用和单元测试
-
例如:
class OrderService:@staticmethoddef create_order(user, items):# 校验库存# 扣减余额# 创建订单# 触发通知return order
👉 最重要的层,能避免 “胖 View” 问题。
5. tasks.py(异步任务层)
- 放 Celery/RQ/定时任务逻辑
- 例如发送邮件、推送通知、批量清理数据
👉 让耗时操作异步化,保持 API 快速响应。
6. urls.py(路由层)
- 定义 API 路由,类似 Spring 的
@RequestMapping
- 逻辑不要写在这里。
7. permissions.py / authentication.py
- 类似 Spring 的拦截器/过滤器
- 处理权限校验、用户认证
8. utils.py / helpers.py
- 存放通用工具函数(时间处理、加密、日志等)
- 避免重复造轮子
- 案例
用 Django REST framework (DRF) 做一个实际案例「订单系统」
一、案例背景
我们做一个最简单的订单系统 API:
- 用户下单
- 查询订单
- 支付订单
涉及到的对象:User
、Order
。
涉及到的逻辑:下单、支付。
二、推荐目录结构
项目叫 shop
,应用叫 orders
:
shop/
│
├── shop/
│ ├── settings.py
│ ├── urls.py
│ ├── wsgi.py
│ └── asgi.py
│
├── apps/
│ └── orders/
│ ├── models.py # 数据模型 (ORM)
│ ├── serializers.py # 序列化 & 校验
│ ├── views.py # 控制器 (调度层)
│ ├── services.py # 业务逻辑层
│ ├── tasks.py # 异步任务 (如发邮件)
│ ├── permissions.py # 权限控制
│ ├── urls.py # 路由定义
│ └── utils.py # 工具方法
│
├── requirements.txt
└── manage.py
和 Spring MVC 对比:
- Controller →
views.py
- Service →
services.py
- Repository/DAO →
models.py
- DTO/VO →
serializers.py
- Filter/Interceptor →
permissions.py
或middleware
三、代码示例(精简版)
1. models.py(数据模型)
from django.db import models
from django.contrib.auth.models import Userclass Order(models.Model):user = models.ForeignKey(User, on_delete=models.CASCADE, related_name="orders")product_name = models.CharField(max_length=100)price = models.DecimalField(max_digits=10, decimal_places=2)is_paid = models.BooleanField(default=False)created_at = models.DateTimeField(auto_now_add=True)def __str__(self):return f"Order({self.product_name}, {self.user.username})"
2. serializers.py(数据序列化 & 校验)
from rest_framework import serializers
from .models import Orderclass OrderSerializer(serializers.ModelSerializer):class Meta:model = Orderfields = ["id", "product_name", "price", "is_paid", "created_at"]read_only_fields = ["id", "is_paid", "created_at"]
3. services.py(业务逻辑层)
from .models import Orderclass OrderService:@staticmethoddef create_order(user, product_name, price):return Order.objects.create(user=user, product_name=product_name, price=price)@staticmethoddef pay_order(order: Order):if order.is_paid:raise ValueError("订单已支付")order.is_paid = Trueorder.save()return order
👉 优点:
- views 变得很轻,只做调度
- 业务逻辑放在
services.py
,可复用、可测试
4. views.py(控制器层)
from rest_framework import viewsets, status
from rest_framework.response import Response
from rest_framework.decorators import action
from .models import Order
from .serializers import OrderSerializer
from .services import OrderServiceclass OrderViewSet(viewsets.ModelViewSet):queryset = Order.objects.all()serializer_class = OrderSerializerdef perform_create(self, serializer):# 下单逻辑交给 servicereturn OrderService.create_order(user=self.request.user,product_name=serializer.validated_data["product_name"],price=serializer.validated_data["price"],)@action(detail=True, methods=["post"])def pay(self, request, pk=None):order = self.get_object()try:order = OrderService.pay_order(order)return Response(OrderSerializer(order).data, status=status.HTTP_200_OK)except ValueError as e:return Response({"error": str(e)}, status=status.HTTP_400_BAD_REQUEST)
5. urls.py(路由层)
from django.urls import path, include
from rest_framework.routers import DefaultRouter
from .views import OrderViewSetrouter = DefaultRouter()
router.register(r"orders", OrderViewSet, basename="order")urlpatterns = [path("", include(router.urls)),
]
四、请求示例
- 创建订单
POST /orders/
{"product_name": "iPhone 16","price": "8999.00"
}
- 查询订单
GET /orders/
- 支付订单
POST /orders/1/pay/
五、为什么这是一个优秀的架构?
✅ 分层清晰:
views
:只负责 HTTP 请求和响应services
:封装业务逻辑,可测试,可复用serializers
:只做数据验证 & 转换models
:只管数据库
✅ 职责单一:每个文件只做一件事,方便维护。
✅ 可扩展:
- 想加支付网关?只改
services.py
。 - 想做异步发邮件?写在
tasks.py
,不影响views.py
。
✅ 团队协作友好:
- 前端/后端都清楚 API 长啥样
- 后端开发知道逻辑放哪里,不会出现“胖 views”