AI 工作實務
Django 入門實作:把客戶與報價表做成有資料約束、可測權限的管理後台
Django 能把資料模型、遷移、認證與管理後台放進同一個開發流程,但畫面出現不等於資料與權限都正確。這份教學用客戶與報價單建立完整本機專案,實測重複單號、刪除保護及唯讀人員的存取邊界,讓交接有可重跑的證據。

Django 能把資料模型、遷移、認證與管理後台放進同一個開發流程,但畫面出現不等於資料與權限都正確。這份教學用客戶與報價單建立完整本機專案,實測重複單號、刪除保護及唯讀人員的存取邊界,讓交接有可重跑的證據。
專題編輯:Derek Chou|AI 技術與架構編輯 · 文件核對 2026.11.09

從 Excel 搬到網站,第一件事是資料規則
假設團隊用試算表管理報價。客戶名稱可能重複輸入,單號可能被覆蓋,離職同事的巨集也沒有人能維護。改用 Django 的理由,應該是把資料關係與操作規則寫清楚,而不是只換一個輸入畫面。
本次練習只有兩個實體:Customer 與 Quote。每張報價必須指向一個客戶,單號不可重複,有報價的客戶不能透過 Django 的刪除流程直接移除。管理後台則分辨「可以進入後台」與「可以讀取、修改特定模型」。這些條件比堆疊許多欄位更適合作為第一輪驗收。
Django Admin 是方便的內部管理工具,但它不會自動變成完整報價系統。本例沒有逐筆負責人授權、簽核程序、價格計算或對外客戶入口;即使資料狀態出現 approved,也不能表示已完成真正的批准制度。
本機專案、版本與檔案分工
本次於 2026 年 11 月 9 日,以 macOS 13.7.8、Python 3.12.14、Django 5.2.19、asgiref 3.13.0、sqlparse 0.6.1 及 SQLite 執行。文件採 Django 5.2 系列;這是本輪驗證範圍,並不宣稱是所有環境的建議組合。
下載 Django 教學專案 並解壓,主要檔案如下:
manage.py
requirements-lock.txt
config/
settings.py
urls.py
quotes/
apps.py
models.py
admin.py
tests.py
migrations/0001_initial.py
config 負責專案設定與網址,quotes 是管理客戶與報價的應用。它們的名稱與資料夾位置有實際作用:應用必須出現在 INSTALLED_APPS,模型才會進入這個專案的管理及遷移流程。下載檔已備好這些連接,不必猜測缺少哪個設定。
步驟一:安裝依賴,先跑系統檢查
在包含 manage.py 的目錄執行:
python3.12 -m venv .venv
source .venv/bin/activate
python -m pip install -r requirements-lock.txt
python manage.py check
預期看到 System check identified no issues。這只是基本專案設定檢查,不等同安全部署驗收。若出現找不到 quotes 或 config,先核對目錄與執行位置;若找不到 Django,檢查虛擬環境,不要把套件隨意裝進系統共用環境。
範例只允許本機主機名稱,開啟除錯模式,並在沒有環境變數時產生只供本機程序使用的隨機 SECRET_KEY。因此服務重啟後,既有 session 可能失效,重新登入即可。這個設定刻意沒有夾帶可用於正式站的秘密,也不應直接公開上網。
步驟二:讓 Model 明確表達可保存的資料
quotes/models.py 定義如下:
from django.db import models
class Customer(models.Model):
name = models.CharField(max_length=200)
def __str__(self):
return self.name
class Quote(models.Model):
class Status(models.TextChoices):
DRAFT = "draft", "草稿"
REVIEW = "review", "待覆核"
APPROVED = "approved", "已核准"
customer = models.ForeignKey(Customer, on_delete=models.PROTECT)
reference_no = models.CharField(max_length=40, unique=True)
status = models.CharField(max_length=10, choices=Status.choices, default=Status.DRAFT)
created_at = models.DateTimeField(auto_now_add=True)
class Meta:
constraints = [models.CheckConstraint(
condition=models.Q(status__in=["draft", "review", "approved"]),
name="quote_status_valid",
)]
def __str__(self):
return self.reference_no
unique=True 讓單號的唯一性受到資料庫約束。狀態同時使用 choices 與 CheckConstraint:前者提供欄位選項,後者避免繞過表單的更新寫入未知狀態。這兩者仍未規定誰可以核准、哪個狀態能轉往哪個狀態;真正簽核需要服務層或流程控制與相應測試。
PROTECT 會在 Django 刪除參照中的客戶時拋出 ProtectedError。要分清它與資料庫的原生刪除政策:on_delete 是 Django 的處理行為,不能假設所有繞過 ORM 的資料庫操作都得到相同應用層保護。正式系統還需要限制直接資料庫權限,並明確定義保留與刪除政策。
步驟三:套用遷移,確認程式與資料庫一致
下載檔包含由本次 Django 環境產生的 0001_initial.py。先檢查 Model 與遷移是否一致,再套用:
python manage.py makemigrations --check --dry-run
python manage.py migrate
python manage.py showmigrations quotes
預期第一個命令顯示沒有新變更,最後的 0001_initial 前面有 [X]。makemigrations 產生模型變更的遷移檔;migrate 才把它套用到資料庫。不能只修改 Model 就宣稱資料庫已更新,也不應把 --fake 當成一般修復方法。
之後若在自己的練習副本新增欄位,先執行 python manage.py makemigrations quotes,檢查新檔,再執行 migrate。遷移檔應與相應程式一起版本控制。既有資料需要補值時,要先安排回填與相容步驟,不能把空資料庫測試的成功直接套用到大量正式資料。
本次另在全新的拋棄式 SQLite 資料庫,驗證 quotes 初始遷移可撤回再套用。撤回初始遷移會移除相關資料表,不能在有業務資料的環境照做。這項測試證明的是教學結構可重建,沒有證明正式資料可復原;正式回復仍需備份還原演練。
步驟四:用測試驗證資料規則與 Admin 權限
執行:
python manage.py test quotes -v 2
本次 8 項測試通過。Django 建立獨立測試資料庫,結束後銷毀;測試資料使用「合成客戶」與 LAB-001 等識別,不包含真實人員或企業記錄。
| 測試情境 | 應觀察到的結果 |
|---|---|
| 建立報價並讀回客戶 | 關聯正確,預設狀態為草稿,建立時間存在 |
| 再建立相同單號 | 資料庫拋出 IntegrityError |
| 刪除仍被報價參照的客戶 | 拋出 ProtectedError,客戶與報價仍存在 |
| 直接更新為未知狀態 | 資料庫約束阻擋 |
| 未登入者查看報價後台 | HTTP 302,導向登入 |
只有 is_staff、沒有模型權限 | HTTP 403 |
有 view_quote 的 staff | 可取得列表與唯讀內容,HTTP 200 |
| 唯讀人員嘗試修改或新增 | HTTP 403,原報價保持不變 |
Admin 的存取需要分層看:有效的 staff 身分只是進入後台的條件,模型的檢視、增加、修改與刪除權限仍須分別設定。不要因為某人是主管,就直接授予 superuser。
這裡使用 Django 測試用戶端,並以 force_login 建立測試 session,因此實際跑過的是後台 view 的授權判斷與 HTTP 回應,不是密碼驗證、瀏覽器點擊或多因素登入。正式驗收若包含那些行為,必須另測。
步驟五:開啟本機後台,再辨認它的用途限制
模型已在 quotes/admin.py 註冊。需要親自瀏覽時,可在練習環境建立自己的本機帳號,再啟動服務:
python manage.py createsuperuser
python manage.py runserver 127.0.0.1:8000
帳號密碼由你在終端機輸入,不要寫入程式、範例檔或版本庫。開啟 http://127.0.0.1:8000/admin/ 後,可先建立合成客戶,再建立報價。superuser 僅適合這個獨立練習的設定工作;用它操作成功,不能取代上一節的一般人員權限測試。
若只要檢查權限結果,前述自動測試已可在不建立可登入密碼的情況下執行。這也避免把教學帳號誤用到正式網站。使用完畢以 Ctrl+C 停止服務。
成功執行後,還有哪些常見誤判?
「有 view 權限,就只會看到自己的資料。」 本例的權限是模型層級,沒有依業務負責人過濾每一筆報價。若不同部門只能看自己的記錄,需要另外設計 queryset 篩選與物件授權,且測試跨部門、直接網址、匯出與搜尋等入口。
「狀態選單有已核准,流程就完成了。」 選項只限制可儲存的值,沒有記錄批准人、時間或先後條件。有修改權限的人仍可能直接改變狀態。實際簽核宜建立明確操作與稽核紀錄,再測不合法轉移會被拒絕。
「ORM 查得到,就不必理解 SQL。」 當列表同時讀取許多關聯資料,仍可能出現大量重複查詢。應以實際頁面與資料量量測查詢數、索引與分頁,而不是把 ORM 當成效能保證。本例資料量很小,未做負載或查詢效能比較。
「check 沒問題,就可以公開。」 一般 check 與部署檢查不同。Django 官方要求針對正式設定執行 check --deploy,妥善處理 SECRET_KEY、DEBUG、HTTPS、Cookie、靜態檔與錯誤回報;runserver 也不是正式部署伺服器。本文的本機設定不能直接代入。
交接前,讓另一個人重建一次
交接時交付程式、精確依賴、遷移檔與測試命令,比交出一份含練習資料的 SQLite 檔更容易重現。接手者應能從空白環境取得相同的 8 項測試結果,指出哪些規則由資料庫執行、哪些由 Django 執行,以及哪些流程尚未建立。
若未來改用 PostgreSQL 或 MySQL,要在該資料庫重新驗證唯一約束、交易、遷移與備份復原。SQLite 的本機結果可作為學習起點,不能替代另一種資料庫及正式資料量的驗收。
官方資料與素材說明
- Django 5.2 Migrations:變更檔、套用與遷移歷程。
- Django Model 欄位參考:唯一性、ForeignKey 與 PROTECT。
- Django Admin 文件:後台設定及檢視、修改等權限。
- Django 部署檢查清單:本機與正式設定的區別。
範例與測試使用合成資料,未連接任何正式企業資料庫。封面為提供之原創概念圖,非 Django 操作截圖;本文未宣稱已完成實際企業簽核流程或正式系統部署。
內容提供:TARAISG。本文由 AI 協助整理與查核;專題編輯為天地人 AI 編輯計畫的策展角色,未宣稱經具名人工或專家審核。
本文由 TARAISG(TIANDIREN AI SOLUTION GROUP)使用 AI 模型產生正文、整理來源並設計實務工具。方法依據與限制列於文末;案例為明確標示的教學假設。未有具名紀錄時,不宣稱經人工或專家審核。
查看內容製作與更正說明