【问题标题】:How to raise a ValidationError AND return a response?如何引发 ValidationError 并返回响应?
【发布时间】:2014-07-28 11:05:52
【问题描述】:

检查我的表单是否有效后,我会执行额外的验证:

def reset_passwd(req):
    if req.method == 'POST':
        form = ResetPasswdForm(req.POST)
        if form.is_valid():
            # extract data
            passwd1  = form.cleaned_data['passwd1']
            passwd2  = form.cleaned_data['passwd2']
            # validate passwd
            if passwd1 != passwd2:
                raise forms.ValidationError('passwords are not the same', 'passwd_mismatch')
            # do stuff...
            return HttpResponseRedirect('/success')
    else:
        form = ResetPasswdForm(req.POST)
    return render(req, 'reset_passwd_form.html', {'form': form})

问题是引发ValidationError 这是一个Exception 当然会中断视图函数的执行,因此不会返回任何响应!

如果form.is_valid() 未执行验证,如何返回绑定表单显示验证错误?

(令人困惑的是,如果表单无效,django 文档说form.is_valid() 会抛出ValidtionErrors,但是当is_valid() 为假时,它必须处理它们,因为调试它会继续执行。)

【问题讨论】:

  • 您应该在clean() 表单的方法中检查这些内容。
  • @Rohan 谢谢,我现在明白了,你可以给它一个答案:)

标签: django python-2.7 django-forms


【解决方案1】:

要验证这种情况,您应该使用表单的clean() 方法,而不是在视图中引发错误。

Cleaning and validating fields that depend on each other 很好地解释了这一点

【讨论】:

    【解决方案2】:

    你需要重写 is_valid() 方法,先调用 super is_valid() (如果返回 false 则返回 false ),然后处理你的错误情况。

    如果您改用 clean(),您将不会受益于其他字段中的“required=True”等内容,并且需要手动检查所有内容。 super().clean() 只是 ... 不检查它,它可能会在访问 clean_data['passwd1'] 时给你 KeyError,除非你自己检查。

    class MyResetPasswdForm(forms.Form):
        passwd1 = forms.CharField(widget=forms.PasswordInput, required=True)
        passwd2 = forms.CharField(widget=forms.PasswordInput, required=True)
    
    def is_valid(self):
        valid = super(MyResetPasswdForm).is_valid()
        if not valid:
            return valid
        if self.cleaned_data.get("passwd1") != self.cleaned_data.get("passwd2"):
            # You cannot raise a ValidationError because you are not in the clean() method, so you need to add the error through the add_error method.
            self.add_error("passwd2", ValidationError('passwords are not the same', 'passwd_mismatch')
            # You could also use None instead of "passwd2" if you do not want the error message to be linked to the field.
        if not self.errors:
            return True
        return False
    

    这样,你会得到预先设置的错误信息,当你调用 super().is_valid() 时,django 会处理字段要求。

    【讨论】:

      猜你喜欢
      • 2021-07-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-02-10
      • 2020-10-11
      • 2020-05-15
      • 2022-07-01
      • 1970-01-01
      相关资源
      最近更新 更多