class BaseForm(RenderableFormMixin):
# 省略
# 省略
# 省略
def clean(self):
"""
Hook for doing any extra form-wide cleaning after Field.clean() has been
called on every field. Any ValidationError raised by this method will
not be associated with a particular field; it will have a special-case
association with the field named '__all__'.
"""
return self.cleaned_data
forms.Form クラスを継承して自作した Form クラスのインスタンスでは、 clean メソッド内で ValidationError を発生させない限り、戻り値として self.cleaned_data を返すようにしてください。
藤本 博子さんの投稿
(投稿ID: 5452)
動画2:26ごろから、clean_<fieldname>、cleanメソッドについて、確認したいことがございます。
お手数をおかけしますが、ご教示いただきたく、どうぞよろしくお願いいたします。
form.is_varid()メソッドで内部的に呼び出されるcleanメソッドについて
・cleanメソッドの場合、親クラス(superクラス)のcleanメソッドを呼び出します。
・clean_<fieldname> メソッドの時は、特定のフィールド属性を指定して、バリデーションをカスタマイズします。
この違いは、以下のような処理の流れがあるからだと思いました。
理解不足で申し訳ございませんが、誤った理解がないか確認したいです。
1.最初に親クラスのcleanメソッドを呼び出し、全フィールドのバリデーションをオーバーライド
2.clean_<fieldname> メソッドの記述がある場合
clean_<fieldname> メソッドで、特定のフィールド属性を検証する場合は、cleaned_data[key]もしくは、 cleanded_data.get()メソッド(keyErrorを発生させない)のいずれかでフィールドを指定して、バリデーションをカスタマイズ
3.clean()メソッドの記述がある場合は、最後に親クラスのcleanメソッドを呼び出してオーバーライド。
カスタマイズした例外処理を記述する。
djangoドキュメント フォームとフィールドの検証を読んだのですが、混乱してしまいました。
「フィールドバリデーションのメソッドは clean() が呼ばれる際に実行されるので、フォームの errors 属性にもアクセスできるようになります。これは各フィールドのクリーニングによって発生した例外をすべて含みます。
Form.clean() をオーバーライドして発生させた例外は、特定のフィールドに結びつかない点に注意してください。
これらは特別な "フィールド" (__all__ と呼ばれます) に格納され、必要に応じて non_field_errors() メソッドを通じてアクセスできます。
特定のフィールドにエラーを紐付けて格納したい場合は、add_error() を呼び出す必要があります。」
自分の画像登録アプリで、forms.Formとforms.ModelFormで、特定のフィールドでバリデーション処理を行うコードを書きました。
そしてテンプレートで個別のフィールドに対しエラーを表示するようにしました。
(ファイルサイズ制限と、file_nameに"test"といれたらValidetionErrorを返す)
ViewはFormViewクラスを継承したクラスベースドビューにしました。
(添削依頼はありません)
forms.py
htmlファイル 選択したファイルサイズが500KB以上、file_nameが"test"の場合、それぞれエラー表示を出して停止
お手数をおかけしますが、どうぞよろしくお願いいたします。
藤本 博子さんのコメント
(コメントID: 8086)
申し訳ございません。
forms.py 自分が書いたコード
間違ってのせたコード
以下のようにsuper().clean()を変数に代入して、変数[key]としても実行はできました。
テストのため、コメントブロックして両方書いていたので間違えました。
小川 慶一さんのコメント
(コメントID: 8087)
>form.is_varid()メソッドで内部的に呼び出されるcleanメソッドについて
>
>・cleanメソッドの場合、親クラス(superクラス)のcleanメソッドを呼び出します。
>・clean_<fieldname> メソッドの時は、特定のフィールド属性を指定して、バリデーションをカスタマイズします。
この違いはなぜあるのかというと、以下の事情からです。
・継承元の forms.Form クラスには clean メソッドが定義されている。
・継承元の forms.Form クラスには clean_<field_name> メソッドが定義されていない。
シンプルに回答するとしたら、上記のとおりです。
なお、通常の forms.Form クラスは、たしかに clean メソッドを有していますが、以下のとおり、その中身は非常にシンプルです。
forms.Form クラスは、BaseForm クラスを継承しています。 clean メソッドは、この BaseForm クラス内で定義されています。これを見てみましょう。
forms.Form クラスを継承して自作した Form クラスのインスタンスでは、 clean メソッド内で ValidationError を発生させない限り、戻り値として self.cleaned_data を返すようにしてください。
最終的に self.cleaned_data を返すための手段として super().clean を呼び出すという方法を取るかどうかは自由です。
なので、以下の2つのどちらでもOKです。
小川 慶一さんのコメント
(コメントID: 8088)
> 添削依頼はないといったのですが
修正版のほうが良いかと思います。
clean メソッドは clean_<field_name> メソッドのあとに実行されるものです。
clean_<field_name> メソッド内に clean メソッドを置こうとするのは、実行順序としておかしいです。
藤本 博子さんのコメント
(コメントID: 8089)
ご回答くださいまして、ありがとうございます。
>この違いはなぜあるのかというと、以下の事情からです。
・継承元の forms.Form クラスには clean メソッドが定義されている。
・継承元の forms.Form クラスには clean_<field_name> メソッドが定義されていない。
ご説明いただき、スッキリしました!
また、BaseForm クラス内で定義されているcleanメソッドをご提示くださいまして、ありがとうございます。
cleanメソッドの活用を、モヤモヤなく、できるようになります。
スッキリしたので、forms.Formクラスを継承したformと、views.generic.FormViewやviews.generic.Viewそれぞれのパターンでモデルのデータベースに連携するコードを書いたりしています。
また、テンプレートで個別のフィールドに対しエラーを表示する機能も追加でき、少し幅が広がりました。
とはいえ、いつも最初はエラー連発なので、スムーズにできるようになりたいです。
いつも分かりやすく解説いただき、とてもありがたいです。
ありがとうございます。