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://www.pswp.cn/web/96219.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/96219.shtml
英文地址,請注明出處:http://en.pswp.cn/web/96219.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

MySQL】從零開始了解數據庫開發 --- 表的操作

永遠記住,你的存在是有意義的, 你很重要, 你是被愛著的, 而且你為這個世界帶來了無可取代的東西。 -- 麥克西 《男孩、鼴鼠、狐貍和馬》-- 從零開始了解數據庫開發創建數據表查看表結構修改數據表結構重命名表復制表刪除表今天我們…

MySQL底層架構設計原理詳細介紹

文章目錄一、MySQL體系結構概覽二、連接層(Connection Layer)1. 連接器(Connectors)2. 連接池(Conncction Pool)三、服務層(Server Layer)1. SQL接口組件(SQL Interface&…

QB/T 4674-2021 汽車內裝飾用聚氨酯束狀超細纖維合成革檢測

汽車內飾品聚氨酯束狀超細纖維合成革是指以海島型雙組份或多組分纖維加工成飛織造布,再經水性聚氨酯樹脂或溶劑型聚氨酯樹脂浸漬、濕法凝固、溶劑或堿液萃取及后整理等工藝制成的汽車內裝飾皮革。QB/T 4674-2021 汽車內裝飾用聚氨酯束狀超細纖維合成革檢測項目測試項…

QML和Qt Quick

QML和Qt Quick QML 和 Qt Quick 是 Qt 框架中緊密相關但概念不同的兩個部分,它們之間的關系可以用如下方式清晰說明: 核心區別概覽??特性????QML????Qt Quick????本質??聲明式編程??語言??基于 QML 的??框架/庫????作用??定…

JavaScript 結構型設計模式詳解

1. 代理模式1.1. 使用場景代理模式在不改變原始對象的前提下,通過代理對象控制對其訪問,通常用于權限控制、延遲加載、遠程調用等場景。在前端開發中,可以通過代理模式對網絡請求、緩存機制等進行控制。1.2. 代碼實現class ApiService {reque…

攝像頭模塊在運動相機中的特殊應用

運動相機作為記錄高速運動場景的專用設備,其攝像頭模塊的設計與普通消費電子產品存在顯著差異。根據行業資料和技術發展,攝像頭模塊在運動相機中的特殊應用主要體現在以下五個維度:一、極端環境適應性設計運動相機的攝像頭模塊針對戶外運動場…

SpringBoot + MinIO/S3 文件服務實現:FileService 接口與 FileServiceImpl 詳解

在企業項目中,文件上傳和管理是非常常見的需求。本文基于 芋道源碼 的實現,介紹如何封裝一個通用的 文件服務 FileService,支持:文件上傳(保存數據庫記錄 存儲文件到 S3/MinIO 等對象存儲)文件下載與刪除文…

Oracle RAC認證矩陣:規避風險的關鍵指南

RAC Certification Matrix(RAC認證矩陣) 是Oracle官方發布的硬件、軟件與操作系統兼容性清單,明確規定了哪些平臺、組件和版本可以正式支持Oracle RAC(Real Application Clusters)的部署。它是搭建或升級RAC環境時必須…

【自然語言處理與大模型】如何通過微調來agent性能?

雖然大模型本身具備一定的指令理解和工具調用潛力,但在實際應用中,尤其是在復雜或專業領域,往往需要通過微調來提升Agent的工具調用能力。問題一:基座模型無法準確識別或選擇特定領域的工具當Agent需要在醫療、金融、法律、工業控…

在 Keil 中將 STM32 工程下載到 RAM 進行調試運行

在 Keil 中將 STM32 工程下載到 RAM 進行調試運行 在使用 STM32 進行調試時,默認情況下代碼會被燒寫到 Flash 中運行。然而,Flash 寫入速度較慢,擦寫次數有限,且調試過程中頻繁燒寫可能影響開發效率。在某些場景下(如快…

【51單片機】【protues仿真】基于51單片機寵物投食系統

目錄 一、主要功能 二、使用步驟 三、硬件資源 四、軟件設計 五、實驗現象 一、主要功能 1、LCD1602液晶顯示時間、溫度、食物重量 2、按鍵手動投喂食物? 3、稱重模塊檢測當前食物重量 4、食物重量小于閾值會聲光警報并自動投喂 二、使用步驟 基于51單片機的寵物投食…

騰訊云負載均衡增加訪問策略后訪問失敗

為了測試,在負載均衡的安全組添加2條安全策略,限制辦公室內IP可訪問,其他IP地址拒絕所有訪問。結果,訪問失敗。經過反復測試,主要是js問價加載失敗,動態接口訪問代碼返回正常。再進行測試,發現去…

CSS的文本樣式

1.文本樣式的分類注意&#xff1a;必須先建立標簽&#xff0c;再在head中修改1.1字體樣式1.1.1字體顏色代碼演示<head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title&g…

R語言讀取excel文件數據-解決na問題

文章目錄安裝R語言運行環境實現代碼遇到的問題總結安裝R語言運行環境 安裝教程連接, 包含國內鏡像快速下載 實現代碼 實現思路&#xff1a;使用python將文件的空字符的位置變成0&#xff0c;生成csv文件后交給R語言處理python實現代碼如下&#xff1a; import pandas as pd…

【Nginx 運維實戰】版本替換:強制 vs 平滑升級全解析

【Nginx 運維實戰】版本替換&#xff1a;強制 vs 平滑升級全解析一&#xff1a;版本替換的兩種思路二&#xff1a;使用場景對比三&#xff1a;實戰1&#xff09;強制替換1.備份舊版本2.替換為新版本3.**賦予執行權限**4.**重啟 Nginx**2&#xff09;平滑替換1.確認進程文件2.備…

MQ-消息隊列

定義 Mssage Queue&#xff1a;消息隊列。它是一種“先進先出”&#xff08;FIFO&#xff09;的數據結構&#xff0c;用于在分布式系統或應用程序之間進行異步通信。組成1. 生產者&#xff08;Producer&#xff09;定義&#xff1a;消息的發送方&#xff0c;負責將業務系…

NVIDIA驅動程序核心的“即時編譯器”(Just-in-Time, JIT Compiler)詳細介紹

我們來詳細、深入地剖析這個位于NVIDIA驅動程序核心的“即時編譯器”&#xff08;Just-in-Time, JIT Compiler&#xff09;。它堪稱CUDA生態系統成功的“幕后英雄”&#xff0c;是連接軟件穩定性和硬件飛速發展的關鍵橋梁。 第一部分&#xff1a;JIT編譯器的本質 首先&#xff…

【PS2025全網最新版】穩定版PS2025保姆級下載安裝詳細圖文教程(附安裝包)(Adobe Photoshop)

今天&#xff0c;給大家帶來PS2025的保姆級下載安裝圖文教程。 前言&#xff1a; Adobe Photoshop 作為業界領先的圖像處理與設計軟件&#xff0c;持續推動著數字創意領域的發展。其應用涵蓋平面設計、攝影后期、UI/UX 設計、影視特效等多個專業方向&#xff0c;為用戶提供強…

分享TWS充電倉方案開發設計

TWS耳機市場“卷”到最后&#xff0c;拼的早已不只是音質&#xff0c;而是續航、交互、體積、成本四位一體。傳統充電倉用多顆IC堆砌&#xff1a;升壓、電量計、霍爾、LED驅動、保護IC……BOM高、貼片復雜、調試周期長。8位MCU把上述功能“一鍋端”&#xff1a;單芯片即完成電源…

【Java實戰?】深入Java單元測試:JUnit 5實戰指南

目錄一、單元測試概述1.1 單元測試概念1.2 單元測試優勢1.3 JUnit 5 框架組成1.4 JUnit 5 環境搭建二、JUnit 5 核心功能實戰2.1 測試類與測試方法2.2 測試生命周期2.3 斷言方法2.4 異常測試三、單元測試進階實戰3.1 參數化測試3.2 測試套件3.3 Mockito 框架3.4 單元測試實戰案…