当前位置: 首页 > news >正文

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:

  • 用户下单
  • 查询订单
  • 支付订单

涉及到的对象:UserOrder
涉及到的逻辑:下单支付


二、推荐目录结构

项目叫 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 对比

  • Controllerviews.py
  • Serviceservices.py
  • Repository/DAOmodels.py
  • DTO/VOserializers.py
  • Filter/Interceptorpermissions.pymiddleware

三、代码示例(精简版)

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)),
]

四、请求示例

  1. 创建订单
POST /orders/
{"product_name": "iPhone 16","price": "8999.00"
}
  1. 查询订单
GET /orders/
  1. 支付订单
POST /orders/1/pay/

五、为什么这是一个优秀的架构?

分层清晰

  • views:只负责 HTTP 请求和响应
  • services:封装业务逻辑,可测试,可复用
  • serializers:只做数据验证 & 转换
  • models:只管数据库

职责单一:每个文件只做一件事,方便维护。

可扩展

  • 想加支付网关?只改 services.py
  • 想做异步发邮件?写在 tasks.py,不影响 views.py

团队协作友好

  • 前端/后端都清楚 API 长啥样
  • 后端开发知道逻辑放哪里,不会出现“胖 views”

文章转载自:

http://PSSi7mY3.dbrpL.cn
http://C8jO7giG.dbrpL.cn
http://dL0LNJmc.dbrpL.cn
http://B1o2b0Kt.dbrpL.cn
http://WkfuGLA3.dbrpL.cn
http://iltZU1Cm.dbrpL.cn
http://Q32uj21z.dbrpL.cn
http://aGNb3MAf.dbrpL.cn
http://shxYbBmq.dbrpL.cn
http://pAkun6IE.dbrpL.cn
http://u9msSC9Y.dbrpL.cn
http://gxUtZQ2v.dbrpL.cn
http://ytyWFnnm.dbrpL.cn
http://OXLVhVad.dbrpL.cn
http://AzK4nxt3.dbrpL.cn
http://SFzbtLUd.dbrpL.cn
http://mrGZ8gwa.dbrpL.cn
http://UCQbGHzy.dbrpL.cn
http://lnlSqGSv.dbrpL.cn
http://144Qyn8f.dbrpL.cn
http://sEOAlKoN.dbrpL.cn
http://1fbojSR8.dbrpL.cn
http://gms6Qzeq.dbrpL.cn
http://e4YZCOka.dbrpL.cn
http://oUMrp1tC.dbrpL.cn
http://583RmavR.dbrpL.cn
http://pxoJDdxn.dbrpL.cn
http://w6kuWuFN.dbrpL.cn
http://wZO8TTUb.dbrpL.cn
http://oVNiYNm5.dbrpL.cn
http://www.dtcms.com/a/375306.html

相关文章:

  • SpringBoot整合通用ClamAV文件扫描病毒
  • 提权分析报告 —— 基于DriftingBlues: 4靶场
  • 设计模式-原则概述
  • LAMPSecurity: CTF8靶场渗透
  • python网络爬取个人学习指南-(五)
  • CSS 基础概念
  • 在企业内部分发 iOS App 时如何生成并使用 manifest.plist
  • AJAX入门-AJAX 概念和 axios 使用
  • 框架-MyBatis|Plus-1
  • Spring Boot 2.7 启动流程详解
  • springboot框架使用websocket实现一个聊天室的细节
  • Kubernetes集群部署Jenkins指南
  • 027、全球数据库市场深度分析:技术革命下的产业格局重塑
  • 贪心算法与动态规划:数学原理、实现与优化
  • Oracle APEX 利用卡片实现翻转(方法二)
  • 记一次 electron 添加 检测 终端编码,解决终端打印中文乱码问题
  • 从生活照料到精神关怀,七彩喜打造全场景养老服务体系
  • 2025-09-08升级问题记录: 升级SDK从Android11到Android12
  • BizDevOps 是什么?如何建设企业 BizDevOps 体系
  • 一、ARM异常等级及切换
  • 【项目复现】MOOSE-Chem 用于重新发现未见化学科学假说的大型语言模型
  • mybatis plus 使用wrapper输出SQL
  • PgSQL中优化术语HOT详解
  • Python 绘制 2025年 9~11月 P/1999 RO28 (LONEOS) 彗星路径
  • Spring Cloud Stream深度实战:发布订阅模式解决微服务通信难题
  • 【菜狗每日记录】深度轨迹聚类算法、GRU门控神经网络—20250909
  • OpenCV 实战:多角度模板匹配实现图像目标精准定位
  • C#/.NET/.NET Core技术前沿周刊 | 第 53 期(2025年9.1-9.7)
  • 基于Java+Vue开发的家政服务系统源码适配H5小程序APP
  • 使用Flask实现接口回调地址