2017-01-28 5 views
5

Djangoバージョン1.10.5フォーム検証が逆

ドキュメントまたはコードソースでこの回答が見つかりません。下のサンプルフォームを使用して、私が定義した順番で実行するsubmitのフォーム検証を期待しています。

したがって、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 
     ] 
    ) 

現在、私は、私は01を使用してフォームを送信すると、validate_statusのバリデータは引き継ぐと、ユーザーがさえ存在しないことを返している1

のIDを持つ1人のユーザーを持っています。私はvalidators.RegexValidatorが最初に返されることを期待していたでしょう。

バリデータの順序全体を逆にすると、検証は必要な順番で行われるように見えます。しかし、コードの可読性は現在実際に起こっていることではありません。

編集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']} 
>>> 

あなたが見ることができるように、降順で実行バリ。

自分の書かれたバリデーターの1つがValidationErrorを正しく投げておらず、エラーのリストが崩れたり、テンプレートのエラーが正しくレンダリングされないと思います。

通常、すべてのバリデーターが実行され、すべての検証エラーがエラーのリストに追加されます。しかし、彼らは降順で実行されます。

+0

ありがとうございます。私はあなたの例を使用しましたが、カスタムバリデータも使用していました。意図したとおりに動作していることは非常に明確で、追跡が必要な根本的な問題があります。 – Diemuzi