:三端角色權限與SKU訂單設計全解析)
做建材類電商項目的時候很多人第一反應是“這不就是個多用戶商城嗎”。但真上手之后你會發(fā)現(xiàn)建材這個行業(yè)和賣衣服賣數(shù)碼完全不一樣SKU維度極其復雜角色之間又有很強的數(shù)據(jù)隔離需求。我最近剛好完整做了一個基于Django的建材銷售平臺角色分了用戶、商家、管理員三端整個項目從建模到落地踩了不少坑這篇文章就把我的完整設計思路、代碼實現(xiàn)和排錯記錄都梳理出來給準備做同類Django項目實戰(zhàn)的新手一個可以直接參考的模板。1. 項目定位與三大角色模型拆解1.1 建材銷售平臺的核心業(yè)務閉環(huán)為什么值得動手做建材銷售平臺本質上是一個B2B2C的電商系統(tǒng)。C端用戶裝修業(yè)主、包工頭、小裝修公司要瀏覽和購買建材B端商家要上架商品、管理庫存、處理訂單平臺管理員則負責審核商家資質、維護類目、處理糾紛。這三者形成一個完整的業(yè)務閉環(huán)商家發(fā)布商品 → 用戶瀏覽下單 → 商家發(fā)貨履約 → 用戶收貨確認 → 管理員全程監(jiān)管。選擇Django來做這個項目我覺得非常合適。建材的品類數(shù)據(jù)模型比普通電商復雜得多比如瓷磚會有規(guī)格、色號、等級、表面工藝等多個維度水泥有袋裝和散裝的區(qū)別計價單位也不統(tǒng)一。Django的ORM抽象能力強模型類可以直接把這些復雜屬性映射成數(shù)據(jù)庫字段配合Django Admin做后臺管理開發(fā)效率非常高。而且平臺天然就有“用戶、商家、管理員”三種角色的權限控制需求Django自帶的認證系統(tǒng)加上自定義用戶模型很輕松就能撐起這套權限體系。這個項目適合誰來學習參考呢如果你是正在做Django項目實戰(zhàn)的新手想找一個不流于表面的完整案例或者你本身在做建材、五金、家居相關行業(yè)的管理系統(tǒng)需要一套可復用的角色權限設計這篇文章都能給你實打實的參考。1.2 三種角色的權限邊界與核心業(yè)務場景先拆解一下三種角色到底要干什么因為權限設計的前提是把業(yè)務場景想清楚否則后面寫代碼全是補丁。用戶端C端消費者注冊登錄、瀏覽商品、按類目和規(guī)格篩選、商品搜索、加入購物車、提交訂單、在線支付、查看訂單狀態(tài)、申請售后。用戶權限的邊界很清晰——只能操作自己的購物車、自己的訂單、自己的收藏夾絕對不能看到商家的庫存和成本信息。商家端B端供貨商商家入駐申請、商品上下架、庫存管理、改價、訂單處理發(fā)貨、退款處理、查看自己店鋪的銷售數(shù)據(jù)。商家的核心訴求是管好自己的“一畝三分地”所以商家端所有功能都要圍繞“當前登錄商家ID”做數(shù)據(jù)隔離不能讓商家A看到商家B的商品和訂單。管理員端平臺運營商用入駐審核、用戶管理、商品類目管理、平臺公告發(fā)布、全量訂單查看、數(shù)據(jù)統(tǒng)計報表。管理員擁有最高權限但不能越權操作具體業(yè)務比如管理員不該直接替商家改價而是通過平臺規(guī)則去約束。這里特別提醒一下權限控制不能只靠前端隱藏按鈕后端必須每一層都校驗。我見過太多項目頁面上的按鈕是藏了但接口沒攔住別人直接構造URL或者抓包就能越權操作。Django里做權限控制核心思路是“裝飾器中間件模型查詢過濾”三層防線后面我會詳細寫實現(xiàn)方案。2. 技術選型為什么是Django 周邊生態(tài)2.1 Django版本、Python環(huán)境與數(shù)據(jù)庫的務實選擇技術選型這件事我的原則是“不追新只求穩(wěn)”。做項目實戰(zhàn)和做技術研究不一樣生產環(huán)境里穩(wěn)定壓倒一切。Python版本建議直接用3.10或3.11這兩個版本目前生態(tài)兼容性最好。Django版本我推薦4.2 LTS這是長期支持版本官方維護周期到2026年4月坑都已經被人踩平了各種第三方庫的兼容性也最好。不建議一上來就用Django 5.x雖然新功能不少但部分第三方庫還沒完全跟上。數(shù)據(jù)庫方面開發(fā)環(huán)境用SQLite完全夠但考慮到建材平臺數(shù)據(jù)量大了以后查詢會變慢生產環(huán)境建議直接上MySQL 8.0或PostgreSQL 14。創(chuàng)建項目的時候用django-admin startproject這個命令創(chuàng)建應用用python manage.py startapp。這里有個經驗之談一個項目不要把所有業(yè)務邏輯都塞進一個app里。我見過不少新手建一個app叫app然后把用戶、商品、訂單全寫在一個models.py里幾千行代碼擠在一起后期維護欲哭無淚。我的做法是拆分多個app每個app只負責一個業(yè)務模塊。django-admin startproject building_mall cd building_mall python manage.py startapp users python manage.py startapp products python manage.py startapp orders python manage.py startapp merchants python manage.py startapp platform2.2 數(shù)據(jù)模型設計一張User表還是擴展Profile這是整個項目最關鍵的決策之一直接影響后面所有代碼的寫法。兩種方案第一種是直接自定義用戶模型繼承AbstractUser加一個user_type字段區(qū)分角色第二種是用Django默認的User再建一個Profile表通過OneToOne關聯(lián)把角色信息放在Profile里。兩種方案都可以但我的建議是如果你還在項目設計階段直接自定義用戶模型最好。因為Django官方文檔明確說了最佳實踐是“從一開始就設置自定義用戶模型”否則中途想切換會非常痛苦。自定義用戶模型的遷移文件一旦生成后面再改涉及大量數(shù)據(jù)遷移操作很可能把數(shù)據(jù)庫搞亂。from django.contrib.auth.models import AbstractUser from django.db import models class User(AbstractUser): ROLE_CHOICES ( (user, 普通用戶), (merchant, 商家), (admin, 管理員), ) role models.CharField(max_length20, choicesROLE_CHOICES, defaultuser, verbose_name角色) phone models.CharField(max_length11, blankTrue, verbose_name手機號) class Meta: verbose_name 用戶 verbose_name_plural verbose_name同時在settings.py里配置AUTH_USER_MODEL這一點特別容易漏。AUTH_USER_MODEL users.User角色字段放在User上登錄的時候一次查詢就能拿到角色信息不用再額外關聯(lián)Profile表查一次減少一次數(shù)據(jù)庫查詢性能更好。當然如果項目已經開始寫了、模型已經遷移過了那就不建議強行改老老實實建Profile表關聯(lián)會穩(wěn)妥很多。2.3 后臺管理現(xiàn)代化改造django-unfold值得一試Django自帶的Admin后臺功能強大但界面老氣建材平臺的運營人員經常要維護類目、審核商品天天對著原生Admin界面確實難受。這里我推薦一個第三方庫django-unfold它能把Django Admin改造成現(xiàn)代化的UI界面?zhèn)冗厵?、主題色、卡片式布局都有非常像現(xiàn)在主流SaaS后端的風格。pip install django-unfoldINSTALLED_APPS [ unfold, # 一定要放在django.contrib.admin之前 django.contrib.admin, ... ]它兼容Django 4.2和5.0安裝后基本不需要改代碼繼承Admin類的地方也都能正常用。這個小改動能讓整個系統(tǒng)的專業(yè)感提升不少商家入駐審核頁面和商品管理頁面用起來舒服得多。我的體驗是django-unfold最大的價值是讓運營團隊的好感度直線上升因為后臺UI舒服了運營錄入數(shù)據(jù)的效率和正確率也跟著上來了。3. 從零搭建項目初始化與核心功能落地3.1 用戶模型擴展與登錄注冊的完整實現(xiàn)用戶系統(tǒng)是整個平臺的地基先從它開始寫。自定義User模型建好之后要處理的就是注冊和登錄邏輯。注冊的時候要區(qū)分角色普通用戶和商家走不同的注冊入口平臺上商家要填寫店鋪名稱和聯(lián)系方式提交入駐申請后要等管理員審核通過才能變成有效商家。注冊接口的核心邏輯很簡單但要注意密碼加密。Django默認的set_password方法會自動加鹽并哈希千萬不要自己存儲明文密碼。這里有一個踩過的坑新手容易圖省事直接user.password request.POST[password]存明文這是致命操作一旦數(shù)據(jù)庫泄露用戶的密碼就全裸奔了。from django.contrib.auth import login, authenticate from django.shortcuts import render, redirect from .forms import UserRegisterForm, MerchantRegisterForm def register_user(request): if request.method POST: form UserRegisterForm(request.POST) if form.is_valid(): user form.save(commitFalse) user.role user user.set_password(form.cleaned_data[password]) user.save() login(request, user) return redirect(home) else: form UserRegisterForm() return render(request, users/register_user.html, {form: form})登錄的邏輯更簡單authenticate傳入用戶名和密碼驗證通過后login寫入會話。登錄成功后注意按角色分發(fā)到不同的首頁普通用戶去商城首頁商家去商家工作臺管理員去平臺后臺。這里我用一個裝飾器來封裝角色判斷后面每個視圖都能復用。from django.core.exceptions import PermissionDenied def role_required(role): def decorator(view_func): def wrapper(request, *args, **kwargs): if not request.user.is_authenticated: return redirect(login) if request.user.role ! role: raise PermissionDenied return view_func(request, *args, **kwargs) return wrapper return decorator用法也很直觀比如商家用戶中心的視圖就這樣標注role_required(merchant) def merchant_dashboard(request): ...裝飾器寫好后每個業(yè)務視圖只要加上一行就能控制訪問角色比到處寫if判斷要清爽得多。但這里有個注意點因為User繼承的是AbstractUserDjango默認的登錄視圖返回的user對象會自動帶上自定義的role字段所以裝飾器里直接取request.user.role是沒問題的。3.2 商品與SKU建模建材行業(yè)特殊字段怎么設計建材商品的建模是整個項目的重頭戲也是最容易暴露行業(yè)認知短板的地方。我一開始直接把所有字段堆在商品表里后來發(fā)現(xiàn)一個致命問題同一種瓷磚可能會有多個規(guī)格、多個色號每種規(guī)格和色號對應不同的庫存和價格。如果把這些都塞在商品表里一條商品記錄根本存不下實際情況。所以商品建模必須拆成兩層商品表Product和SKU表ProductSKU。商品表存的是通用信息品牌、類目、標題、主圖、描述SKU表存的是具體售賣規(guī)格每個SKU對應一個價格和一個庫存數(shù)量。class Product(models.Model): name models.CharField(max_length200, verbose_name商品名稱) category models.ForeignKey(products.Category, on_deletemodels.PROTECT, verbose_name類目) brand models.CharField(max_length100, verbose_name品牌) material models.CharField(max_length100, verbose_name材質, blankTrue) description models.TextField(verbose_name商品描述, blankTrue) cover_image models.ImageField(upload_toproducts/cover/, verbose_name主圖) merchant models.ForeignKey(settings.AUTH_USER_MODEL, on_deletemodels.CASCADE, verbose_name所屬商家) is_active models.BooleanField(defaultTrue, verbose_name是否上架) created_at models.DateTimeField(auto_now_addTrue) class ProductSKU(models.Model): product models.ForeignKey(Product, on_deletemodels.CASCADE, related_nameskus, verbose_name所屬商品) spec_value models.CharField(max_length100, verbose_name規(guī)格值) # 比如 800x800mm 啞光灰 color models.CharField(max_length50, verbose_name色號, blankTrue) grade models.CharField(max_length20, verbose_name等級, choices((a,優(yōu)等品),(b,一等品),(c,合格品)), blankTrue) unit models.CharField(max_length20, verbose_name單位, default平方米) price models.DecimalField(max_digits10, decimal_places2, verbose_name銷售單價) stock models.IntegerField(default0, verbose_name庫存數(shù)量)這里有幾個建材行業(yè)的特殊點分享給大家單位不統(tǒng)一的問題。瓷磚按平方米、水泥按袋/噸、板材按張、電線按卷。所以unit字段不能省下單和展示時必須明確標注計價單位否則用戶下單時看到的價格單位和自己預期的不一致售后糾紛能讓你崩潰。等級的概念。瓷磚同一型號會有優(yōu)等品和一等品的價格差異石膏板也分不同等級。這個在普通電商里不太會遇到但在建材里是常規(guī)操作。價格波動快。建材的原材料價格受市場行情影響明顯商家需要經常調價。所以價格放在SKU表而不是商品表方便特定規(guī)格單獨調價。同時建議加一個價格變動日志表記錄每一次調價歷史方便財務對賬。3.3 訂單流轉與庫存扣減一個事務解決并發(fā)問題訂單模塊是整個平臺業(yè)務邏輯最密集的地方主要涉及訂單狀態(tài)管理和庫存扣減。訂單我拆成訂單主表和訂單明細表主表記錄收貨人信息、總金額、狀態(tài)等明細表記錄商品SKU、購買數(shù)量、單價。訂單狀態(tài)用一個choices字段維護可以定義如下狀態(tài)序列待支付 → 已支付/備貨中 → 已發(fā)貨 → 已簽收 → 已完成以及異常狀態(tài)已取消、售后中、退款成功。狀態(tài)流不能跳變比如待支付狀態(tài)下不能直接變成已發(fā)貨這些業(yè)務規(guī)則可以在模型中定義方法避免散落在各個視圖里。庫存扣減是電商平臺最經典的問題——并發(fā)。兩個用戶同時買同一件商品庫存只剩一件如果代碼先讀庫存再更新庫存就會發(fā)生超賣庫存變成負數(shù)。Django里解決這個問題有兩種常用方案。第一種方案是使用select_for_update在事務里對SKU記錄加行鎖。from django.db import transaction with transaction.atomic(): sku ProductSKU.objects.select_for_update().get(idsku_id) if sku.stock quantity: raise ValueError(庫存不足) sku.stock - quantity sku.save() # 創(chuàng)建訂單明細等操作select_for_update的作用是鎖定該行記錄其他事務要操作這行時就必須等待當前事務提交這樣并發(fā)請求就能串行化不會出現(xiàn)超賣。第二種方案是用F表達式直接在數(shù)據(jù)庫層面原子操作from django.db.models import F ProductSKU.objects.filter(idsku_id, stock__gtequantity).update(stockF(stock) - quantity)filter里的stock__gte保證庫存足夠才更新update返回受影響的行數(shù)如果返回值是0說明庫存不足。這個方法更輕量性能也比加行鎖好適合高并發(fā)的場景。但有些場景還是需要先查后寫的比如下單時要同時校驗商品是否上架在售所以我會把F表達式和事務結合使用既保證一致性又減少鎖等待。還有一個業(yè)務細節(jié)需要決定庫存扣減的時機。我采用的是“下單預占支付確認”的策略。用戶提交訂單后先把庫存鎖定扣減庫存如果用戶沒有在15分鐘內支付訂單自動取消并釋放庫存。這樣做的好處是用戶下單后商品不會被別人買走體驗更好。壞處是預占庫存的時間內其他用戶看到的庫存是減少的有可能影響銷售。權衡之下建材這種低頻高客單價的商品預占策略更合適。3.4 ORM高頻操作實戰(zhàn)查詢、更新、刪除對象Django的ORM用好了能省很多事但用不好經常踩坑。這里我把項目中最高頻的幾種操作列一遍。查詢是重頭戲。建材商品的類目很多用戶經常要用多個條件組合篩選按類目、按品牌、按材質、按價格區(qū)間。組合查詢的核心是Q對象和filter的動態(tài)拼接。比如前端傳多個篩選條件后端用字典動態(tài)構造filter參數(shù)from django.db.models import Q filters {is_active: True} if category_id: filters[category_id] category_id if brand: filters[brand] brand if min_price: filters[skus__price__gte] min_price if max_price: filters[skus__price__lte] max_price products Product.objects.filter(**filters).distinct()注意這里用了skus__price這種跨表查詢因為價格在SKU表商品和SKU是一對多的關系所以要用雙下劃線跨關系過濾加distinct()是為了去重否則一個商品有多個SKU時會返回多條重復記錄。聚合統(tǒng)計也經常用。比如商家工作臺要看到“我的商品數(shù)量”“本月訂單總金額”用annotate比遍歷Python再統(tǒng)計效率高得多from django.db.models import Sum, Count merchant_orders Order.objects.filter(merchantrequest.user, created_at__month8) total_amount merchant_orders.aggregate(totalSum(total_amount)) total_count merchant_orders.aggregate(countCount(id))關于關聯(lián)查詢性能有一個必須提到的點select_related和prefetch_related。查詢訂單列表時如果訂單關聯(lián)了用戶和SKU用select_related能把外鍵關聯(lián)的表一次性join查出來避免在循環(huán)里逐條查詢外鍵數(shù)據(jù)。這就是著名的N1問題列表有50條訂單如果每個訂單都要查一次用戶表就會多出50條SQL用select_related之后只有1條SQL。至于刪除對象Django的delete()方法有一個很容易被人忽略的特點它是級聯(lián)的。刪除一個商品它關聯(lián)的所有SKU會被一并刪除刪除一個用戶他的所有訂單也會被刪光。這有時候很危險。在銷售平臺里商品和訂單都是重要的業(yè)務數(shù)據(jù)物理刪除意味著數(shù)據(jù)徹底沒了。我的處理思路是業(yè)務數(shù)據(jù)一律軟刪除用is_activeFalse代替delete()。# 下架商品軟刪除而不是物理刪除 product.is_active False product.save()# 如果要物理刪除先確認沒有訂單關聯(lián)且做好級聯(lián)評估 order_count OrderItem.objects.filter(sku__productproduct).count() if order_count 0: raise ValueError(該商品存在歷史訂單禁止刪除) product.delete()Django的delete()還會返回一個元組第一個元素是刪掉的對象總數(shù)第二個元素是每個模型刪除數(shù)量的字典如果調試的時候想確認到底刪了什么可以print出來看看我調級聯(lián)刪除問題時就靠這個定位到某個外鍵忘了加on_delete。3.5 文件上傳與圖片資源管理的配置建材商品離不開圖片用戶的購買決策很大程度依賴于商品實拍圖。Django的文件上傳配置不算復雜但很容易在部署階段卡住。核心配置有三處MEDIA_URL、MEDIA_ROOT以及開發(fā)環(huán)境下的媒體路由。# settings.py MEDIA_URL /media/ MEDIA_ROOT BASE_DIR / media# urls.py開發(fā)環(huán)境專用 from django.conf import settings from django.conf.urls.static import static urlpatterns static(settings.MEDIA_URL, document_rootsettings.MEDIA_ROOT)開發(fā)環(huán)境里這行代碼能讓你直接通過/media/訪問上傳的圖片非常方便調試。但要注意生產環(huán)境絕對不能這么配因為Django自帶開發(fā)服務器不適合承載靜態(tài)文件圖片由Nginx直接處理配置會在server塊里加一個location /media/指向MEDIA_ROOT目錄。還有一個容易忽略的點用戶上傳的文件名可能包含中文或特殊字符在上傳到服務器后容易引起編碼問題。我習慣了在上傳時統(tǒng)一重命名文件比如用時間戳加隨機串來命名import os, uuid from django.utils import timezone def rename_upload(instance, filename): ext os.path.splitext(filename)[1].lower() new_name f{timezone.now().strftime(%Y%m%d%H%M%S)}_{uuid.uuid4().hex}{ext} return os.path.join(products, instance.product.merchant.username, new_name)這樣處理之后文件名永遠是純ASCII的配合CDN做分發(fā)也不會有問題我建議所有上傳字段都用這個邏輯。4. 常見問題與排查實錄4.1 權限校驗失效后臺接口被未授權訪問這是我遇到的第一個嚴重問題。項目初版做完后我用一個普通用戶賬號測試發(fā)現(xiàn)竟然能直接通過URL訪問商家的訂單管理頁面。原因很簡單我這個視圖只在前端判斷了按鈕顯隱后端接口探到URL就直接返回數(shù)據(jù)了根本沒做角色校驗。排查過程用瀏覽器開發(fā)者工具抓包偽造一個商家工作臺的URL發(fā)現(xiàn)返回了200狀態(tài)碼和數(shù)據(jù)。修復方案就是上面說的role_required裝飾器并且給所有需要權限的視圖統(tǒng)一加上。這里給新手一個可復用的檢查方法把所有URL路徑整理成一張表逐個標注需要什么角色能訪問然后用不同角色賬號逐一實測。權限表用Excel或者Markdown記錄都可以關鍵是覆蓋所有視圖別漏。4.2 圖片上傳后無法顯示這個問題幾乎人人都遇到過。開發(fā)環(huán)境下圖片顯示正常部署到服務器后圖片鏈接404。原因可能有三個MEDIA_ROOT路徑不對、MEDIA_URL沒有匹配到靜態(tài)文件服務、Nginx沒有配置media目錄映射。我的排查順序是先檢查服務器上文件是否真的上傳成功去MEDIA_ROOT對應目錄看文件在不在再檢查Nginx配置看location /media是否指向了正確的目錄最后看Django有沒有在DEBUGFalse時配置靜態(tài)文件處理。這里有個坑很多教程里的static函數(shù)只在DEBUGTrue時生效生產環(huán)境必須靠Nginx或S3這類獨立存儲服務這個區(qū)分得非常清楚不然部署就踩雷。4.3 N1查詢導致接口慢得離譜項目經理反饋商品列表頁打開要三秒多。我用Django Debug Toolbar看一下SQL查詢次數(shù)商品列表30條記錄總共執(zhí)行了30多次額外SQL每個商品都查了一次所屬商家的店鋪名。這就是典型的N1查詢問題。修復方案是對商品外鍵字段加上select_relatedproducts Product.objects.select_related(merchant).filter(is_activeTrue)對于商家和商品這類一對一/多對一關系select_related用SQL的JOIN一次性查出來對于多對多關系或者反向外鍵要使用prefetch_related它會先查主表再查關聯(lián)表在Python內存里做關聯(lián)避免JOIN造成結果集膨脹。這兩個方法用對了查詢效率可以有數(shù)量級的提升。4.4 delete()級聯(lián)刪除的慘痛教訓有一次我在測試環(huán)境模擬下架滯銷商品手滑用了product.delete()而不是軟刪除。當時還覺得測試環(huán)境無所謂結果發(fā)現(xiàn)這個商品關聯(lián)的所有SKU、訂單明細都被級聯(lián)刪除了而訂單明細被刪除后平臺的銷售報表數(shù)字全部不正常。最后只能從備份里恢復數(shù)據(jù)折騰了大半天。這次的教訓我總結成兩條鐵律物理刪除前必須檢查所有外鍵關聯(lián)。Django模型里每個ForeignKey的on_delete參數(shù)都要想清楚CASCADE雖然有但并不適合業(yè)務數(shù)據(jù)。訂單、訂單明細這類涉及交易的數(shù)據(jù)用PROTECT保護起來有引用就禁止刪除。業(yè)務數(shù)據(jù)一定要做軟刪除。重要數(shù)據(jù)永遠不物理刪除用status字段的狀態(tài)位控制可見性查詢時統(tǒng)一過濾is_active。這樣就算誤操作也有后悔藥吃。4.5 庫存超賣問題并發(fā)場景下的數(shù)據(jù)一致性平臺上線第三天就遇到問題某個瓷磚SKU只剩5件庫存但后臺顯示下單成功了7單。這就是并發(fā)超賣。初版代碼是“先查庫存再扣減”的邏輯sku ProductSKU.objects.get(idsku_id) if sku.stock quantity: sku.stock - quantity sku.save()兩個人同時請求都讀到庫存5都滿足1的條件都執(zhí)行了扣減最后庫存變成4但事實上賣出了2件超賣了1件。修復方法前面已經寫了要么用F表達式原子更新要么用select_for_update加行鎖。我最終的方案是select_for_update配合事務因為庫存扣減的同時還要創(chuàng)建訂單明細、更新狀態(tài)多個寫操作需要放在同一個事務里保證原子性。5. 一些開發(fā)過程中的個人心得我前后做了兩個版本的建材銷售平臺第一版完全按普通電商的思路來設計結果在商品建模和業(yè)務邏輯上被運營吐槽得體無完膚。第二版深入到建材行業(yè)的細節(jié)里從SKU拆分到計價單位再到等級劃分每一條都是根據(jù)實際業(yè)務反推出來的。如果你準備用Django做這種多角色平臺項目我強烈建議動手前先把業(yè)務角色畫清楚。用戶、商家、管理員三者在數(shù)據(jù)上的邊界在項目開始時就通過模型的ForeignKey和查詢條件定義好后期才不會越改越亂。另外如果打算用AI輔助編碼來快速搭一個Django項目我的經驗是AI生成代碼速度快但ORM行為和權限校驗邏輯不能全信特別是外鍵的on_delete參數(shù)和查詢性能這部分關鍵代碼還是要自己把邏輯捋順了再放進去。最后再分享一個調試小妙招。Django項目調試時配置好Django Debug Toolbar每寫一個列表頁或者詳情頁都要看一眼SQL查詢次數(shù)和頁面響應時間。這條習慣能幫你提前發(fā)現(xiàn)絕大部分性能雷區(qū)比上線后再排查靠譜得多。這個項目做完之后我對Django的模型設計自信了不少下一次再遇到類似的B2B2C平臺需求從需求到第一版上線節(jié)奏會快很多。