今回のお題
今回はdjangoのclean
メソッドについてまとめます。
以下の記事の続きですね。
目次
- cleanメソッドとは
- clean_xxxを作る
- cleanメソッドを作る
- まとめ
cleanメソッドとは
独自のバリデーションを設定するためのメソッドで、その名の通りclean()
またはclean_フィールド名()
という形式で命名します。
単一のフィールドを検証する場合であればclean_xxx()
、複数のフィールドにまたがった検証を行うのであればclean()
メソッドを用います。
clean_xxxメソッドを作る
まずは単一のフィールドを検証するclean_xxx()
メソッドを作ります。
cleanメソッド
は基本的にforms.pyに定義します。
class ReviewForm(ModelForm):
def clean_body(self):
body = self.cleaned_data.get("body")
if body == "ばか":
raise forms.ValidationError("ばかと入力しないで下さい")
return body
class Meta:
fields = "__all__"
ポイントは3つで、
- 検証するフィールドの値は
cleaned_data
を用いて取得する - 検証に引っかかった場合には
forms.ValidationError
を投げる - 最後にフィールド値を返す。
この3つを行う必要があります。
ちなみに、cleanメソッド
全般に言えることですが、組み込みバリデーターや自作メソッドと違ってmodels.py
で適用するバリデーターとして登録する必要はありません。
なぜかというと、djangoではis_valid
メソッドが実行された時点でclean_フィールド名
メソッドやclean
メソッドが自動で実行される仕様になっているからのようです。
cleanメソッドを作る
では、次にcleanメソッド
を作ります。
# ...省略...
def clean(self):
cleaned_data = super().clean()
name = cleaned_data.get("name")
nickname = cleaned_data.get("nickname")
if name == nickname:
raise forms.ValidationError("登録者名とニックネームを同じにしないで下さい")
return cleaned_data
基本的にはclean_xxx
メソッドと同じですが、clean
メソッドに関してはデフォルトで用意されているのでそれをオーバーライドする形になります。
参考:django/forms/forms.pyのcleanメソッド
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
# ただ単にcleaned_dataを返すだけ
まとめ
- forms.pyの中でcleanメソッドを定義すると自動で実行されるようになる。
- メソッド名は単一のフィールドを検証する場合には
clean_フィールド名
、複数のフィールドが絡む場合にはclean
- メソッドの戻り値は検証しているフィールド値もしくは
cleaned_data
全体で、検証違反があった場合にはforms.ValidationError
を投げる。 - 後者の
clean
メソッドに関してはオーバーライド形式で定義する。
個人的には自作バリデータよりも便利だと感じたので、積極的に使っていきます。