django の Form とバリデーションについてまとめてみた。
https://docs.djangoproject.com/en/1.5/ref/forms/validation/
今回使用した django のバージョンは 1.5。
日本語のページ もありますが情報が古い(最新で v1.4) ので、
なるべく英語版の、自分が使っているバージョンにあったものを読んだ方がいいです。
バリデーションの実行順序
以下の順に、フォームおよびフィールドの各メソッドが呼ばれる。
1. <Field>.to_python() 2. <Field>.validate() # <Field>.run_validators() # <Field>.clean() 3. <Form>.clean_<fieldname>() 4. <Form>.clean()
コメントアウトしたメソッドは 2 と 3 の間で呼び出されるそうだが、使用することは(おそらく)ない。
1. <Field>.to_python()
最初に呼ばれ、フォームなどの入力値そのものを引数として受け取り正しい python のデータ型に変換する。
できなければ ValidationError を raise する。
- 引数: あり
- return: 必要
2. <Field>.validate()
1 の to_python
によって適切な型に変換された後の値を受け取り、
フィールド固有のバリデーションを行う。
validator ではできない or validator を使いたくないバリデーションのロジックを
このメソッドで記述する。
引数で渡された値の 変更は行うべきでない。
- 引数: あり
- return: 不要
3. <Form>.clean_<fieldname>()
フォームの特定の属性に対するクリーニング。
- 引数: なし
- なので、フォームの
self.cleaned_data
(dict) から取得する必要がある
- なので、フォームの
- return: 必要(クリーニングした後の値)
4. <Form>.clean()
最後。フォームの 複数のフィールドにまたがるバリデーションを行いたい場合 はここに記述する。
(具体的には後述)
- 引数:なし
- return: 必要(最終的な
self.cleaned_data
) - このメソッド内でエラーを raise した場合、(いずれかのフィールドではなく)
__all__
という名の特殊なフィールドに関連づけられる。
エラーはnon_field_errors()
でアクセス可能
http://docs.djangoproject.jp/en/latest/ref/forms/validation.html
オーバライドされた Form.clean() の送出するエラーは、フォームの いずれかのフィールドではなく、(
__all__
という名の) 特殊な「フィールド」に関連づけられます。エラーはnon_field_errors()
でアクセス できます。エラーをフォームの特定のフィールドに関連付けたいのなら、 後で解説 する、フォームの_errors
属性にアクセスする必要があります。
clean() の例:複数のフィールドにまたがるバリデーション
class ContactForm(forms.Form): subject = forms.CharField(max_length=100) message = forms.CharField() sender = forms.EmailField() recipients = MultiEmailField() cc_myself = forms.BooleanField(required=False) def clean(self): cleaned_data = super(ContactForm, self).clean() cc_myself = cleaned_data.get("cc_myself") subject = cleaned_data.get("subject") if cc_myself and subject: # Only do something if both fields are valid so far. if "help" not in subject: raise forms.ValidationError("Did not send for 'help' in " "the subject despite CC'ing yourself.") # Always return the full collection of cleaned data. return cleaned_data
TODO
- 1 ~ 4 までのメソッドを含む、簡単なサンプルを書いて試してみる(ユニットテストも含む)
- バリデーター (validator) について調べる