首页 > 解决方案 > Django:验证器返回 False 但 form.is_valid() == True

问题描述

我创建了一个自定义验证器,它检查中的上限数字RangeField是否低于某个数字。

问题是我可以在调试模式下看到Validator.compare返回FalseDjango引发DataError

值“21474834555”超出了第 1 行整数类型的范围:...NULL,“cena”=NULL,“poznamka”='',“rozloha”='[-214748...

我无法弄清楚为什么它应该在此之前引发此错误ValidationError

我知道这个数字超出了范围,这就是我创建Validator.

看法

class DopytUpdateView(LoginRequiredMaklerAccessMixin, UpdateView):
    model = Dopyt
    form_class = DopytForm
    template_name = 'dopyty/dopyt.html'

形式

class DopytForm(forms.ModelForm):

    class Meta:
        model = Dopyt
        fields = [...'rozloha',...]

验证器

class RangeCompleteMaxValueValidator(MaxValueValidator):
    def compare(self, a, b):
        upper_ok = (a.upper > b) if a.upper else True
        lower_ok = (a.lower > b) if a.lower else True
        return upper_ok and lower_ok

模型

class Dopyt(TimeStampedModel):
    ...
    rozloha = IntegerRangeField(null=True, blank=True, verbose_name='Rozloha [m2]',
                                validators=[RangeCompleteMinValueValidator(-2147483648),
                                            RangeCompleteMaxValueValidator(2147483647)])

你知道它为什么会这样吗?

编辑

如您所见,验证器返回False

在此处输入图像描述

标签: djangopython-3.xdjango-modelsdjango-formsdjango-2.0

解决方案


表单验证器看不到模型验证器,如果要避免到达模型层,必须使用 clean

您验证器在您的模型实例上运行,因此当您要保存时...而 form.is_valid 在表单中运行时,因此此验证不会到达您的模型...要在您的表单上验证您的逻辑,您应该使用 clean

from django import forms

class ContactForm(forms.Form):
    # Everything as before.
    ...

    def clean(self):
        cleaned_data = super().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."
                )

https://docs.djangoproject.com/en/2.0/ref/forms/validation/


推荐阅读