在Django Model表单中覆盖clean()方法时返回cleaning_data

时间:2017-10-06 12:56:35

标签: python django django-forms

我需要覆盖Django Model表单中的clean()方法,以对输入的数据执行其他唯一性检查。

此页面提供了实施细节: https://docs.djangoproject.com/en/1.11/ref/forms/validation/在这里复制:

 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."
            )

但是我很困惑为什么这个方法在函数结束时没有return cleaned_data?当然这是正确的做法吗?

3 个答案:

答案 0 :(得分:4)

看一下django的_clean_form方法:

def _clean_form(self):
    try:
        cleaned_data = self.clean()
    except ValidationError as e:
        self.add_error(None, e)
    else:
        if cleaned_data is not None:
            self.cleaned_data = cleaned_data

阅读forms doc 上的最后一个要点,特别是ModelForm doc的这一点。

如果clean方法引发ValidationError,则会将错误添加到表单的错误中。 如果clean方法返回了任何内容并且没有出现任何错误,则表单将使用该方法作为其cleaned_data属性。否则它将保持其“旧”。

在您的情况下,clean方法所做的一切都是验证表单的某个方面。

答案 1 :(得分:0)

您感兴趣的示例是覆盖相关字段的clean方法。这意味着它验证了涉及多个字段的逻辑。将此视为表单clean方法。因此,在这种情况下,您不想返回任何值。

正如doc所说:

"在实践中这样做时要小心,因为它会导致表单输出混乱。我们正在展示这里的可能性,并让您和您的设计师在您的特定情况下找出有效的方法。"

这取决于您的具体情况,但根据我在某个特定字段上覆盖clean的经验,如果验证通过,您将要返回它。同样,这仅适用于一个领域。

这是文档中的另一个示例,但是对于一个字段验证:

def clean_recipients(self):
    data = self.cleaned_data['recipients']
    if "fred@example.com" not in data:
        raise forms.ValidationError("You have forgotten about Fred!")

    # Always return a value to use as the new cleaned data, even if
    # this method didn't change it.
    return data

答案 2 :(得分:0)

在 Django < 1.7 中,form.clean() 需要返回 cleaned_data 的字典。
此方法可能仍会返回要使用的数据字典,但不再需要。