1. 程式人生 > 程式設計 >Django框架model模型物件驗證實現方法分析

Django框架model模型物件驗證實現方法分析

本文例項講述了Django框架model模型物件驗證實現方法。分享給大家供大家參考,具體如下:

模型物件的驗證

驗證一個模型涉及三個步驟:

  • 驗證模型的欄位 —— Model.clean_fields()
  • 驗證模型的完整性 —— Model.clean()
  • 驗證模型的唯一性 —— Model.validate_unique()

當呼叫模型的full_clean() 方法時,這三個方法都將執行。當使用ModelForm時,is_valid() 將為表單中的所有欄位執行這些驗證。如果你計劃自己處理驗證出現的錯誤,或者你已經將需要驗證的欄位從ModelForm 中去除掉,你只需呼叫模型的full_clean()

方法。

Model.full_clean(exclude=None,validate_unique=True)

該方法按順序呼叫Model.clean_fields()、Model.clean() 和Model.validate_unique()(如果validate_unique 為True),並引發一個ValidationError,該異常的message_dict 屬性包含三個步驟的所有錯誤。可選的exclude 引數用來提供一個可以從驗證和清除中排除的欄位名稱的列表。ModelForm 使用這個引數來排除表單中沒有出現的欄位,使它們不需要驗證,因為使用者無法修正這些欄位的錯誤。注意,當你呼叫模型的save() 方法時,full_clean() 不會 自動呼叫。如果你想一步就可以為你手工建立的模型執行驗證,你需要手工呼叫它。例如:

from django.core.exceptions import ValidationError
try:
  article.full_clean()
except ValidationError as e:
  # Do something based on the errors contained in e.message_dict.
  # Display them to a user,or handle them programmatically.
  pass

full_clean() 第一步執行的是驗證每個欄位。

Model.clean_fields(exclude=None)

這個方法將驗證模型的所有欄位。可選的exclude 引數讓你提供一個欄位名稱列表來從驗證中排除。如果有欄位驗證失敗,它將引發一個ValidationError。

full_clean() 第二步執行的是呼叫Model.clean()。如要實現模型自定義的驗證,應該覆蓋這個方法。

Model.clean()

應該用這個方法來提供自定義的模型驗證,以及修改模型的屬性。例如,你可以使用它來給一個欄位自動提供值,或者用於多個欄位需要一起驗證的情形:

import datetime
from django.core.exceptions import ValidationError
from django.db import models
class Article(models.Model):
  ...
  def clean(self):
    # Don't allow draft entries to have a pub_date.
    if self.status == 'draft' and self.pub_date is not None:
      raise ValidationError('Draft entries may not have a publication date.')
    # Set the pub_date for published items if it hasn't been set already.
    if self.status == 'published' and self.pub_date is None:
      self.pub_date = datetime.date.today()

Model.full_clean() 類似,呼叫模型的save() 方法時不會引起clean() 方法的呼叫。

在上面的示例中,Model.clean() 引發的ValidationError 異常通過一個字串例項化,所以它將被儲存在一個特殊的錯誤字典鍵NON_FIELD_ERRORS中。這個鍵用於整個模型出現的錯誤而不是一個特定欄位出現的錯誤:

from django.core.exceptions import ValidationError,NON_FIELD_ERRORS
try:
  article.full_clean()
except ValidationError as e:
  non_field_errors = e.message_dict[NON_FIELD_ERRORS]

若要引發一個特定欄位的異常,可以使用一個字典例項化ValidationError,其中字典的鍵為欄位的名稱。我們可以更新前面的例子,只引發pub_date 欄位上的異常:

class Article(models.Model):
  ...
  def clean(self):
    # Don't allow draft entries to have a pub_date.
    if self.status == 'draft' and self.pub_date is not None:
      raise ValidationError({'pub_date': 'Draft entries may not have a publication date.'})
    ...

最後,full_clean() 將檢查模型的唯一性約束。

Model.validate_unique(exclude=None)

該方法與clean_fields() 類似,只是驗證的是模型的所有唯一性約束而不是單個欄位的值。可選的exclude 引數允許你提供一個欄位名稱的列表來從驗證中排除。如果有欄位驗證失敗,將引發一個 ValidationError。

注意,如果你提供一個exclude 引數給validate_unique(),任何涉及到其中一個欄位的unique_together 約束將不檢查。

希望本文所述對大家基於Django框架的Python程式設計有所幫助。