5

ビジネス ロジックに関連するすべての検証をフォームに残すのではなく、モデルに移行しようとしています。しかし、ここで難しい状況が発生したので、SO コミュニティに相談したいと思います。

私の SignupForm (モデル フォーム) では、次のフィールド固有の検証を行って、入力メールがまだ存在しないことを確認しています。

def clean_email(self):
    email = self.cleaned_data['email']

    if ExtendedUser.objects.filter(email=email).exists():
        raise ValidationError('This email address already exists.')
    return email

公式ドキュメントによると、この検証をモデルに移すとしたらclean()、対応するモデルのExtendedUser. しかし、ドキュメントには次のことも記載されています。

Model.clean() によって発生した ValidationError 例外はすべて、特定のフィールドではなくモデル全体に​​関連付けられているエラーに使用される特別なキー エラー ディクショナリ キー NON_FIELD_ERRORS に格納されます。

つまり、 ではclean()、それから発生したエラーを特定のフィールドに関連付けることができません。モデルがフォームに似たものを提供するかどうか疑問に思っていましたclean_<fieldname>()。そうでない場合、この検証ロジックをどこに配置しますか?またその理由は?

4

2 に答える 2

3

cleanメソッドをに変換validatorし、フィールドを宣言するときにそれを含めることができます。

もう1つのオプションは、モデルフィールドをサブクラス化し、そのcleanメソッドをオーバーライドすることです。

clean_<field name>ただし、フォームに対して実行できるようなメソッドの定義に直接相当するものはありません。フォームの場合とは異なり、個々のフィールドにエラーを割り当てることもできません。

于 2012-03-22T00:11:48.410 に答える
1

コメントで述べたように、この検証はモデルフォームレベルで処理する必要があると思います。それでもモデルの近くで行う方がよいと思われる場合は、変更できないため、dbレベルで直接変更することをお勧めします。

ALTER TABLE auth_user ADD UNIQUE (email)

これは、モンキーパッチ認証なしでモデルにunique=True制約を追加するための不適切な方法です。User

要望に応じて、ベースモデルフォームから継承して、さまざまなフォームをカスタマイズするための良い方法を実行する必要があると思います。この良い例は、django-registrationにあります。唯一の違いは、あなたから継承する親フォームの代わりに、forms.FormそれをmodelFormにすることです。

class MyBaseModelForm(ModelForm):
    class Meta:
        model = MyModel

次に、それを継承して、この基本モデルからさまざまなフォームを作成できます。

class OtherFormWithCustomClean(MyBaseModelForm):
    def clean_email(self):
       email = self.cleaned_data['email']
       if ExtendedUser.objects.filter(email=email).exists():
          raise ValidationError('This email address already exists.')
    return email
于 2012-03-22T00:35:13.950 に答える