Logo

新人日誌

首頁關於我部落格

新人日誌

Logo

網站會不定期發佈技術筆記、職場心得相關的內容,歡迎關注本站!

網站
首頁關於我部落格
部落格
分類系列文

© 新人日誌. All rights reserved. 2020-present.

Django 新手指南:modelform 數據提交原理解析

最後更新:2024年12月24日Python

本文為 Django 分類功能系列教學,第 9 篇:

  1. 新手指南:如何設計 Django 分類功能
  2. 新手指南:如何定義需求並實現分類模型
  3. 新手指南:Service 模型與 related_name 的作用
  4. 新手指南:透過自訂管理指令初始化分類資料
  5. 自訂管理指令:程式碼詳細解說
  6. 新手指南:深入理解 get_or_create 的作用與用法
  7. Django 新手指南:新增分類欄位的邏輯
  8. Django 新手指南:如何正確編輯服務分類
  9. Django 新手指南:modelform 數據提交原理解析 👈 所在位置
  10. Django 分類頁畫面顯示功能指南
  11. Django 外鍵查詢入門:category_id 與 category.id 的區別

在 Django 表單設計中,為下拉選單的選項設定適當的 value 屬性是關鍵。

雖然可以使用分類的名稱或 ID 作為 value,但大多數情況下,選用 ID 更加穩定和高效。

本文將結合 ModelForm 的數據處理邏輯,詳細解析選項提交數據的行為差異,幫助新手做出最佳選擇。


ModelForm 的數據處理邏輯

Django 的 ModelForm 根據 HTML 表單的控件類型,處理數據時行為有所不同。

以下是常見控件的行為解析:

對於 <input>(單行輸入框)

傳送的內容

  • 提交時,傳送的是用戶實際輸入的內容,而不是 value 屬性中初始化的值。

處理方式

  • ModelForm 將提交的內容直接映射到模型字段,並進行驗證。

特點

  • value 屬性僅用於初始化表單的預設值,不影響提交的內容。

範例

HTML:

<input type="text" name="title" value="預設值">

用戶輸入「新內容」,後端接收到:

title=新內容

對於 <textarea>(多行輸入框)

傳送的內容

  • 提交時,傳送的是用戶輸入的多行內容,而非 <textarea> 的初始化值。

處理方式

  • 與 <input> 類似,提交內容會直接映射到模型字段。

範例

HTML:

<textarea name="description">預設描述</textarea>

用戶輸入「這是修改後的描述」,後端接收到:

description=這是修改後的描述

對於 <select>(選項)

傳送的內容

  • 表單提交時,傳送的是選中選項的 value 值(例如分類的 ID)。

處理方式

  • ModelForm 會將 value 值對應到模型字段的內容:
    • 如果字段是外鍵,Django 會用此 value 在關聯的模型中查找對應的實例。

特點

  • 顯示的名稱(<option> 的文字內容)與提交的數據(value 屬性)分離。

範例

HTML:

<select name="category">
    <option value="1">教育</option>
    <option value="2" selected>運動</option>
</select>

用戶選擇「運動」,後端接收到:

category=2

Django 會自動將 2 對應到分類模型中的 ID 為 2 的實例。


關鍵差異:value 和用戶輸入的內容

以下是不同控件的提交邏輯對比:

控件類型提交的內容value 屬性是否影響提交
<select>選中項目的 value是,提交時採用 value
<input>用戶實際輸入的內容否,只用於初始化預設值
<textarea>用戶實際輸入的內容否,只用於初始化預設值
提交的內容選中項目的 value
value 屬性是否影響提交是,提交時採用 value
提交的內容用戶實際輸入的內容
value 屬性是否影響提交否,只用於初始化預設值
提交的內容用戶實際輸入的內容
value 屬性是否影響提交否,只用於初始化預設值

為什麼選項應該使用 ID

使用名稱作為 value

當選項的 value 設定為分類名稱時,提交的數據包含的是分類名稱。

優點

  • 直觀:提交數據是分類名稱(如「教育」),對查看數據的人更友好。

缺點

  1. 名稱可能重複
    • 如果有多個分類名稱相同,後端可能無法正確識別分類。
  2. 查詢效率低
    • 名稱查詢比使用 ID 查詢耗時更多,特別是在分類數量較多時。
    • 後端需要使用名稱來查找分類:
category = Category.objects.get(name=request.POST['category'])
  1. 易受變更影響
    • 如果分類名稱改動,歷史數據可能變得無法對應或解析。

使用 ID 作為 value(推薦)

當選項的 value 設定為分類的主鍵 ID 時,提交數據包含的是分類的唯一標識符。

優點

  1. 唯一性與穩定性
    • ID 是資料庫的主鍵,具有唯一性且不會因分類名稱變更而影響。
  2. 查詢效率高
    • 使用 ID 查詢分類更快速: category = Category.objects.get(id=request.POST['category'])
  3. 適配業界標準
    • 使用 ID 作為 value 是常見做法,與大多數框架的標準流程一致。

缺點

  • 對人類不直觀
    • 提交的數據可能是這樣: { "category": 2 } 用戶無法直接得知數字 2 代表什麼分類,但這通常不是問題,因為分類名稱可以通過 ID 查詢顯示給用戶。

實例對比

假設有以下分類資料:

分類名稱分類 ID
餐飲1
教育2
運動3
分類 ID1
分類 ID2
分類 ID3

用戶選擇「教育」,提交的數據和後端處理邏輯如下:

項目使用 ID使用名稱
提交的數據category=2category=教育
後端查詢代碼Category.objects.get(id=2)Category.objects.get(name="教育")
潛在問題無名稱可能重複或更改
使用 IDcategory=2
使用名稱category=教育
使用 IDCategory.objects.get(id=2)
使用名稱Category.objects.get(name="教育")
使用 ID無
使用名稱名稱可能重複或更改

最終建議

為什麼使用 ID 是最佳選擇?

  1. 唯一性與穩定性
    • ID 確保分類能被唯一標識,避免因名稱重複或變更導致的問題。
  2. 性能更高
    • 使用 ID 查詢效率優於名稱查詢,特別是在數據量大的情況下。
  3. 標準化流程
    • 與大多數框架兼容,是通用的最佳實踐。

使用名稱的場景(僅限簡單應用)

  • 當分類數據量少且名稱保證唯一時,可以考慮用名稱作為 value。

總結

  1. 對於 <select> 選項:
    • 提交的數據由 value 屬性決定,建議使用分類的 ID。
  2. 對於輸入控件(<input> 和 <textarea>):
    • 提交的數據是用戶輸入的內容,value 僅用於初始化。
  3. 最佳選擇:
    • 使用分類 ID 作為下拉選單的 value 屬性,能確保數據的唯一性和系統穩定性,適用於多數場景。

透過以上建議,您可以設計更高效、穩定且可擴展的 Django 表單!

目前還沒有留言,成為第一個留言的人吧!

發表留言

留言將在審核後顯示。

Python

目錄

  • ModelForm 的數據處理邏輯
  • 對於 <input>(單行輸入框)
  • 對於 <textarea>(多行輸入框)
  • 對於 <select>(選項)
  • 關鍵差異:value 和用戶輸入的內容
  • 為什麼選項應該使用 ID
  • 使用名稱作為 value
  • 使用 ID 作為 value(推薦)
  • 實例對比
  • 最終建議
  • 為什麼使用 ID 是最佳選擇?
  • 使用名稱的場景(僅限簡單應用)
  • 總結