1. save() 方法
• 機制:
• 呼叫 save() 方法時,會先對模型例項的欄位進行驗證(如欄位型別、長度約束等)。
• 如果模型定義了 clean() 或者欄位設定了驗證規則(如 validators),這些規則也會被執行。
• 驗證透過後,Django 才會將資料儲存到資料庫中。
• 觸發的邏輯:
• 觸發模型的 pre_save 和 post_save 訊號。
• 執行模型的 full_clean() 方法,對資料完整性進行檢查。
• 適用場景:
• 儲存或更新單個物件時,確保資料完整性和驗證邏輯得以執行。
• 示例:
1 # 假設模型如下: 2 class Employee(models.Model): 3 name = models.CharField(max_length=50) 4 salary = models.PositiveIntegerField() 5 6 # 建立或更新例項 7 emp = Employee.objects.get(id=1) 8 emp.salary = -100 # 負數會違反 PositiveIntegerField 的規則 9 emp.save() # 丟擲 ValidationError
2. update() 方法
• 機制:
• update() 是基於查詢集(QuerySet)的批次操作方法,直接生成 SQL UPDATE 語句並執行,不載入模型例項,也不執行欄位驗證。
• 不會觸發模型的 clean() 方法或任何訊號(如 pre_save 和 post_save)。
• 操作是資料庫層面的直接更新。
• 適用場景:
• 批次更新多個物件時,用於提高效率,因為不會載入模型例項或執行驗證。
• 示例:
1 # 批次更新 2 Employee.objects.filter(salary__lt=3000).update(salary=3500) 3 4 # 單個更新(仍然是批次更新語法) 5 Employee.objects.filter(id=1).update(salary=-100) # 不會丟擲驗證錯誤,直接寫入資料庫
3. 主要區別
特性 |
save() | update() |
欄位驗證 | 會進行欄位驗證,觸發 full_clean() | 不進行欄位驗證,直接生成 SQL 語句 |
訊號觸發 | 觸發 pre_save 和 post_save 訊號 | 不觸發任何訊號 |
操作範圍 | 僅限單個例項 | 支援批次操作,可更新多個記錄 |
效能 | 較低,需載入例項並逐一儲存 | 較高,直接生成 SQL 並批次執行 |
用途 | 確保資料驗證和完整性 | 快速批次更新,無需模型例項 |
4. 使用建議
1. 使用 save() 時:
• 對單個例項進行更新或插入,並希望確保資料驗證邏輯得以執行。
• 例如,在使用者提交表單後儲存物件時。
2. 使用 update() 時:
• 在不需要欄位驗證和訊號觸發的情況下,進行批次更新操作以提升效能。
• 例如,批次修改某些狀態欄位時。