2017-01-28 46 views
5

Django版本1.10.5表單驗證逆轉

我在文檔或代碼源中找不到此答案。使用下面的示例表格,我期待我的表單驗證提交以我已定義的順序運行。

所以validators.RegexValidator,validators.MinLengthValidator等將按此順序運行。但是,當提交表單時,驗證器會以相反的順序運行。

其中validate_status,validate_employee_id等將運行。

這是預期嗎?

class FormLogin(forms.Form): 
    # Employee ID 
    employee_id = forms.CharField(
     label=_('employeeId'), 
     required=True, 
     widget=forms.TextInput(
      attrs={ 
       'id': 'employee_id', 
       'placeholder': _('employeeId'), 
       'class': 'form-control' 
      } 
     ), 
     validators=[ 
      validators.RegexValidator('^[1-9][0-9]*$', _('validatorStartsWithZero')) 
      validators.MinLengthValidator(1), 
      validators.MaxLengthValidator(20), 
      validate_employee_id, 
      validate_status 
     ] 
    ) 

目前,我有1.

的ID 1個用戶當我提交使用01的形式,將validate_status驗證接管並返回,用戶甚至不存在。我會期待validators.RegexValidator首先返回,因爲它前面有一個0。

如果我顛倒了驗證器的整個順序,那麼驗證似乎按我想要的順序工作。但是現在代碼可讀性並不明確,這就是實際發生的情況。

編輯1盪滌例如更多信息

+1

檢查Field類的run_validators方法:https://github.com/django/django/blob/e07e743e0c375b380748561d18b975c8211a4a01/django/forms/fields.py#L129好像驗證器應該按正確的順序運行。 – neverwalkaloner

+0

是什麼讓你相信,他們以相反的順序運行?至少我從django的來源看不到他們爲什麼應該這樣做。字段類的默認驗證器總是首先運行,然後按照它們定義的順序運行自定義的驗證器,然後運行特定於字段的驗證器,例如如果設置了'max_length',則在'CharField'上設置max_length驗證器。 – trixn

+0

@trixn用更多的數據更新我的問題,使其更加清晰。 – Diemuzi

回答

1

我寫了這個小測試代碼重現此。

from django import forms 


def validate_1(value): 
    print('RUNNING VALIDATOR 1') 
    raise ValidationError(
     'validation error 1', 
     params={'value': value}, 
    ) 

def validate_2(value): 
    print('RUNNING VALIDATOR 2') 
    raise ValidationError(
     'validation error 2', 
     params={'value': value}, 
    ) 


class FormLogin(forms.Form): 
    # Employee ID 
    employee_id = forms.CharField(validators=[ 
     validate_1, 
     validate_2 
    ]) 

運行它:

>>> f = FormLogin({'employee_id': '01'}) 
>>> f.is_valid() 
RUNNING VALIDATOR 1 
RUNNING VALIDATOR 2 
False 
>>> f.errors 
{'employee_id': ['validation error 1', 'validation error 2']} 
>>> 

正如你可以看到,其中以降序執行的驗證。

我假設你的一個自己寫的驗證器沒有正確地拋出ValidationError,這樣錯誤列表就搞砸了,或者你沒有正確地在模板中顯示錯誤。

通常所有驗證器都會運行,並且每個驗證錯誤都會附加到錯誤列表中。但他們按降序排列。

+0

謝謝你。我用你的例子,但也使用我的自定義驗證程序,很明顯,它是按預期工作,我有一個根本問題,不向我展示,我需要追蹤。 – Diemuzi