即使缺少所需的值,Django 验证也会调用 clean()

Posted

技术标签:

【中文标题】即使缺少所需的值,Django 验证也会调用 clean()【英文标题】:Django validation calling clean() even when required value missing 【发布时间】:2012-09-09 02:34:21 【问题描述】:

我是 Django 新手,对表单处理期间的验证步骤有些困惑。我知道默认情况下需要所有表单字段类型(在我的情况下为 ModelForm)。我假设 Django 会引发 VaidationError 以防必填表单字段留空没有调用表单的 clean 方法。

这就是为什么我没有检查以下clean()方法中是否设置了任何数据:

def clean(self):
    date =  self.cleaned_data.get('date')
    time_start = self.cleaned_data.get('time_start')
    time_end = self.cleaned_data.get('time_end')
    user_type = self.cleaned_data.get('user_type')

    if Event.objects.filter(user_type=user_type, date=date, 
                            time_start__lt=time_start, 
                            time_end__gt=time_start).exclude(pk=self.instance.pk).count():
        raise forms.ValidationError("Overlapping with another event.")

提交表单时将所有字段留空会导致

ValueError: 不能使用 None 作为查询值。

如果我删除我的 clean() 方法,我将得到预期的 ValidationErrors,因为没有填写必填字段 - 这是我在 clean() 方法仍然存在时所期望的。

知道什么会导致这种情况发生吗?如果 Django 在调用 clean 之前 不检查所需的值,我会感到惊讶。

【问题讨论】:

【参考方案1】:

这很奇怪,因为字段的验证是在调用表单的clean 方法之前执行的。此外,从字段引发的错误存储在form.my_field.errors 中,而从表单的 clean 方法返回的错误累积在 form.non_field_errors 中。

以下是表单中执行验证的顺序:

full_clean()
    |
Field clean() [field's built-in clean method]
    |
Form clean_*() [custom validation method for field]
    |
Form clean() [form's clean method]
    |
cleaned_data/errors

【讨论】:

好的,谢谢。但是如何在每个字段的内置 clean 方法中捕获 ValidationError 而不必遇到 clean() 中的 None 类型。我必须在 clean() 中再次检查 self.cleaned_data 吗? 是的。如果先前引发了validationError,则该字段的值将不在self.cleaned_data 字典中。所以如果你想检查一个字段的值是否存在,你必须检查它。例如if self.cleaned_data.get('date') is not None: .... 您还可以检查字段的清理方法(例如def clean_date)中的字段是否引发错误,方法与上述if self.cleaned_data.get('date') is not None:相同 好的,现在明白了。感谢您的澄清。 这在docs中有很好的解释

以上是关于即使缺少所需的值,Django 验证也会调用 clean()的主要内容,如果未能解决你的问题,请参考以下文章

即使缺少所需架构的部分,GraphQL POST 也会通过

跟进:缺少 django Modelform 中所需的 Charfield 被保存为空字符串并且不会引发错误

C# Google 地理编码:即使遵循所需的步骤,也会不断拒绝权限

即使选择了文件,也会显示CodeIgniter文件验证

xcode 验证错误:info.plist 文件缺少所需的密钥:CFBundleVersion

无法从 Django 应用程序调用芹菜任务(缺少位置参数)