【问题标题】:How can I exclude few fields from validation in forms如何从表单中的验证中排除几个字段
【发布时间】:2013-05-17 03:52:32
【问题描述】:

我在这样的 Django 表单中有 10 个字段

class SearchForm(forms.Form):
    student_number                 = forms.CharField(required=False)
    final_date                      = forms.DateField(required=False)
    location_area                   = forms.FloatField(required=False)

在我的form.is_valid() 中,我想从验证中排除几个字段,例如

[location_area, final_date] 和其余的都执行验证或只想验证 charfields 而不是 select fields。

我该怎么做?

【问题讨论】:

    标签: django forms validation


    【解决方案1】:

    在Meta 类表单中,您可以排除字段:

    class SearchForm(forms.Form):
        # form fields here
        class Meta:
            exclude = ('location_area', 'final_date',)
    

    如果你不想从表单中排除字段并且仍然不想验证它们,那么为表单编写一个自定义字段清理方法,它什么都不做:

    class SearchForm(forms.Form):
        # form fields here
    
        def clean_location_area(self):
            location_area = self.cleaned_data['location_area']
            return location_area
    

    【讨论】:

    • 我只想从验证中排除,但仍想在表单上显示它们
    • 我试过了,但它不起作用,因为在 clean_%s % name 之前调用了 field.clean,所以我仍然收到验证错误。 github.com/django/django/blob/master/django/forms/forms.py#L292
    • 为什么要处理未经处理的数据?至少您应该验证正确的字段类型。如果您尝试将char 保存在integer 字段中,这将导致数据库错误。
    • 或者如果您想允许用户将特定字段留空然后更改您的模型并允许字段null=True, blank=True
    • @user2392209 也许您需要将ModelMultipleChoiceField 子类化为clean 方法不进行任何验证的子类。
    【解决方案2】:

    基本上,您可以覆盖表单的 init 方法: 例如

    class SearchForm(forms.Form):
    # form fields here
    
    def __init__(self, post_data=None, post_files=None):
         if post_data and post_files:
             self.base_fields.remove(field_name)
             super(SearchForm, self).__init__(post_data, post_files)
         else:
             super(SearchForm, self).__init__()
    

    所以,基本上当你得到你可以使用的表格时:SearchForm() 当您将数据发布到您可以使用的表单时:SearchForm(request.POST, request.FILES)。 在__init__ 方法中,我们使用post_data 和post_files 检查请求是post 还是get。因此,如果它是帖子,我们将从 base_field 中删除该字段,以便它不会检查该字段的验证。

    在 Django 1.11 中测试

    【讨论】:

    • 您的答案是否适用于所有 Django 版本(包括可能由 OP 使用的版本)或者是否特定于版本?
    • 我不确定所有的 django 版本,但我在 1.11 上尝试过
    • forms.Form 的 Django 源代码指出:“base_fields 类属性是字段的类范围定义。因为特定的实例 类可能想要更改self.fields,我们通过复制base_fields 在此处创建self.fields。实例应始终修改self.fields;它们不应修改self.base_fields。"
    • self.fields 中的值基本上是在调用 forms.Form 的 init 方法时出现的,所以如果我们想在调用 init 之前进行一些修改forms.Form 那么我们必须使用 base_fields
    猜你喜欢
    • 2023-03-15
    • 2014-06-14
    • 2011-10-17
    • 2010-12-11
    • 2020-02-24
    • 2020-12-03
    • 2016-07-22
    • 2015-06-30
    • 1970-01-01
    相关资源
    最近更新 更多