2012-03-21 34 views
4

我想所有的業務邏輯相關的驗證移到模型,而不是讓他們在表單中。但在這裏我有一個棘手的情況,爲此我想諮詢SO社區。確實Django模型提供類似形式的clean_ <fieldname>()的東西嗎?

在我SignupForm(模型的形式),我有以下具體領域的驗證,以確保輸入的電子郵件不存在。

def clean_email(self): 
    email = self.cleaned_data['email'] 

    if ExtendedUser.objects.filter(email=email).exists(): 
     raise ValidationError('This email address already exists.') 
    return email 

如果我是這個驗證移到模型,根據官方的文檔,我會把它放進相應的模型,ExtendedUserclean()。但是,文檔還提到了以下內容:由Model.clean(提出

任何ValidationError例外)將被存儲在 一個特殊的鍵錯誤辭典鍵,NON_FIELD_ERRORS,用來 對於那些依賴於整個錯誤模型而不是一個特定的 場

這意味着,與clean(),我不能從它與具體領域提出的錯誤關聯。我想知道模型是否提供了與表單'clean_<fieldname>()類似的東西。如果不是,你會在哪裏放置驗證邏輯,爲什麼?

+0

」不是個這個邏輯與形式相關嗎?你爲什麼認爲它會更好地生活在模型中?在我看來,這將是django中模型的預期用法。 – vascop 2012-03-22 00:30:38

+0

@VascoP - 我只是想將所有業務邏輯集中在模型中。首先,它在設計方面更加有組織。從概念上講,我認爲驗證生活在模型中是有意義的。此外,當我有基於相同模型的多個模型表單時,它具有共享相同驗證的好處。 – tamakisquare 2012-03-22 00:49:33

+2

您也可以繼承與給定模型相關的更一般的模型,併爲每個不同的表單創建子模型。 – vascop 2012-03-22 00:55:54

回答

3

你可以在你的清潔方法轉換成validator,包括它在聲明領域。

另一種選擇是繼承模型字段,並覆蓋其清潔方法。

但是有定義clean_<field name>方法,你可以做形式無直接等同。你甚至不能指派錯誤單個字段,as you can do for forms

1

正如評論指出,我相信你應該處理在水平的ModelForm此驗證。如果你仍然覺得這將是更好地做到這一點更接近模型,因爲它們不能被改變,我將在數據庫級別直接建議的改變:

ALTER TABLE auth_user ADD UNIQUE (email) 

這就是窮人的方式在沒有猴子補丁驗證的情況下將unique=True約束添加到User模型。

按照要求,我認爲一個好的方式去定製不同的形式應該從基本的ModelForm繼承來完成。 django-registration就是一個很好的例子。唯一的區別是,代替母體形式forms.Form繼承你會讓它的ModelForm:

class MyBaseModelForm(ModelForm): 
    class Meta: 
     model = MyModel 

然後,您可以從它繼承並從這個基本模型做出不同的形式:

class OtherFormWithCustomClean(MyBaseModelForm): 
    def clean_email(self): 
     email = self.cleaned_data['email'] 
     if ExtendedUser.objects.filter(email=email).exists(): 
      raise ValidationError('This email address already exists.') 
    return email 
相關問題