同时验证两个字段

5xu*_*xum 5 django django-models

我正在查看这段文档:

清理和验证相互依赖的字段

该文档解释了如何完成字段依赖,但我有一个稍微不同的问题:

假设我有一个包含两个字段的模型:

class MyModel(models.Model):
    field1 = models.CharField(max_length=200)
    field2 = models.CharField(max_length=200)
Run Code Online (Sandbox Code Playgroud)

并说两个字段之一是隐藏的,所以模型表单看起来像这样:

class MyModelForm(forms.ModelForm):
    class Meta:
        ...

        widgets = {'field2': forms.HiddenImput()}
Run Code Online (Sandbox Code Playgroud)

现在,当用户填写表单时,我 (on clean_field1) 也填写field2. 现在,我想将发生的任何错误报告field2为关于field1. 这是因为此刻,用户不知道自己做错了什么!

我试图做的是,在 ModelForm 定义中:

def clean(self):
    cleaned_data = super(MyModelForm, self).clean()
    # Do something here
    return cleaned_data
Run Code Online (Sandbox Code Playgroud)

因为这是 Django 页面上显示的内容。但是,问题是clean方法执行的时候,字典self.errors是空的,不知道怎么办……

Oth*_*man 4

我不确定我的答案。但是,我们假设您正在使用field1数据来生成field2价值。您可以使用自定义方法生成它并将其分配给方法中的字段__init__。这将为您提供稍后清理这两个字段的好方法。

\n\n
class MyModelForm(forms.ModelForm):\n\n    def __init__(self, *args, **kwargs):\n        super(MyModelForm, self).__init__(*args, **kwargs)\n\n        # now lets generate field2 data using field1 data.. \n        self.data[\'field2\'] = self.field[1] * 154220\n\n    class Meta:\n        widgets = {\'field2\': forms.HiddenInput()}    \n\n\n    def clean_field1(self):\n        ## Here you can do validation for field1 only.\n        ## Do it like field2 is not exisited. \n\n\n    def clean_field2(self):\n        ## Here you can do validation for field2 only.\n        ## Do it like field1 is not exisited. \n\n    def clean(self):\n        """\n        In here you can validate the two fields\n        raise ValidationError if you see anything goes wrong. \n        for example if you want to make sure that field1 != field2\n        """\n        field1 = self.cleaned_data[\'field1\']\n        field2 = self.cleaned_data[\'field2\']\n\n        if field1 == field2:\n            raise ValidationError("The error message that will not tell the user that field2 is wrong.")\n\n        return self.cleaned_data\n
Run Code Online (Sandbox Code Playgroud)\n\n
\n\n

更新

\n\n

如果您希望该clean方法在特定字段中引发错误:

\n\n
\n

请注意,由 Form.clean() 重写引发的任何错误都不会与任何特定字段相关联。它们进入一个特殊的 \n \xe2\x80\x9cfield\xe2\x80\x9d (称为all),如果需要,您可以通过 \n non_field_errors() 方法访问它。如果要将错误附加到表单中的特定字段,则需要调用 add_error()。

\n
\n\n

因此,您可以使用 Django 文档来add_error()实现您想要实现的目标。

\n\n

代码可以是这样的

\n\n
def clean(self):\n    """\n    In here you can validate the two fields\n    raise ValidationError if you see anything goes wrong. \n    for example if you want to make sure that field1 != field2\n    """\n    field1 = self.cleaned_data[\'field1\']\n    field2 = self.cleaned_data[\'field2\']\n\n    if field1 == field2:\n        # This will raise the error in field1 errors. not across all the form\n        self.add_error("field1", "Your Error Message")\n\n    return self.cleaned_data\n
Run Code Online (Sandbox Code Playgroud)\n\n

请注意,上述方法是 Django 1.7 及更高版本中的新方法。

\n\n

https://docs.djangoproject.com/en/dev/ref/forms/api/#django.forms.Form.add_error

\n