模型表单中的 Django 必填字段

Posted

技术标签:

【中文标题】模型表单中的 Django 必填字段【英文标题】:Django required field in model form 【发布时间】:2010-11-11 04:53:30 【问题描述】:

我有一个表单,当我不想要它们时,会根据需要显示几个字段。这是来自models.py的表格

class CircuitForm(ModelForm):
    class Meta:
        model = Circuit
        exclude = ('lastPaged',)
    def __init__(self, *args, **kwargs):
        super(CircuitForm, self).__init__(*args, **kwargs)
        self.fields['begin'].widget = widgets.AdminSplitDateTime()
        self.fields['end'].widget = widgets.AdminSplitDateTime()

在实际的Circuit模型中,字段是这样定义的:

begin = models.DateTimeField('Start Time', null=True, blank=True)
end = models.DateTimeField('Stop Time', null=True, blank=True)

我的views.py在这里:

def addCircuitForm(request):
    if request.method == 'POST':
        form = CircuitForm(request.POST)
        if form.is_valid():
            form.save()
            return HttpResponseRedirect('/sla/all')
    form = CircuitForm()    
    return render_to_response('sla/add.html', 'form': form)

我该怎么做才能使这两个字段不再是必需的?

【问题讨论】:

通过更改小部件无法要求这些字段。如果模型有 (null=True, blank=True),modelForm 将其呈现为 required=False。 看来你是对的。这些字段本身不是必需的,但小部件中的日期和时间字段是必需的。 【参考方案1】:

如果您不想修改模型中字段的空白设置(这样做会破坏管理站点中的正常验证),您可以在 Form 类中执行以下操作:

def __init__(self, *args, **kwargs):
    super(CircuitForm, self).__init__(*args, **kwargs)

    for key in self.fields:
        self.fields[key].required = False 

重新定义的构造函数不会损害任何功能。

【讨论】:

【参考方案2】:

如果模型字段的空白=True,则在表单字段中将 required 设置为 False。否则,required=True

这里是这样说的:http://docs.djangoproject.com/en/dev/topics/forms/modelforms/

看起来你做的一切都是正确的。 你可以检查self.fields['end'].required的值。

【讨论】:

请注意,某些字段(例如BooleanField)在其构造函数(docs.djangoproject.com/en/dev/_modules/django/db/models/fields/…)中硬编码为blank=True。因此,设置 blank=False 将静默失败。您必须在表单的构造函数中使用 self.fields[…].required = True 来强制这些字段的所需行为。另见code.djangoproject.com/ticket/22282。【参考方案3】:

扩展 DataGreed 的答案,我创建了一个 Mixin,允许您在 Meta 类上指定一个 fields_required 变量,如下所示:

class MyForm(RequiredFieldsMixin, ModelForm):

    class Meta:
        model = MyModel
        fields = ['field1', 'field2']
        fields_required = ['field1']

这里是:

class RequiredFieldsMixin():

    def __init__(self, *args, **kwargs):

        super().__init__(*args, **kwargs)

        fields_required = getattr(self.Meta, 'fields_required', None)

        if fields_required:
            for key in self.fields:
                if key not in fields_required:
                    self.fields[key].required = False

【讨论】:

如果这个 mixin 的用户也将覆盖 __init__ 会发生什么? mixin 还能用吗?多重继承如何解决? @user3599803 当您覆盖 __init__ 时,您应该始终调用 super(),就像在我的 sn-p 中所做的那样。 所以如果我理解的话——我创建了一个表单和 MyForm 的子类。我从init()调用super,它会调用mixin init,但是当djangl form init被调用时? 是的,还有其他资源在讨论这个问题,如果你愿意,你也可以创建一个新问题,请让 cmets 在这里讨论这个特定问题的主题。【参考方案4】:

这不是答案,但对于通过 Google 找到此问题的其他任何人来说,还有一点数据:这发生在我身上,它是在带有 DateField 的模型表单上。它要求设置为 False,模型具有“null=True,blank=True”,如果我在 clean() 方法中查看它,表单中的字段显示 required=False,但它仍然说我需要一个有效日期格式。我没有使用任何特殊的小部件,即使我明确设置 input_formats=['%Y-%m-%d', '%m/%d/%Y', ',我也会收到“输入有效日期”消息%m/%d/%y', ''] 在表单域上。

编辑:不知道它是否会帮助其他人,但我解决了我遇到的问题。我们的表单在字段中有一些默认文本(在这种情况下,表示该字段的单词“to”是结束日期;该字段称为“end_time”)。我专门在表单的 clean() 方法中寻找“to”这个词(我也尝试过 clean_end_time() 方法,但它从未被调用)并将 clean_data 变量的值设置为 None,如 @987654321 中所建议的那样@。但是,这些都不重要,因为(我猜)模型的验证已经吐出了“to”的无效日期格式,而我没有机会拦截它。

【讨论】:

【参考方案5】:

这是使用小部件时的错误:

解决方法: Using Django time/date widgets in custom form

或票号 12303

【讨论】:

【参考方案6】:

来自model field documentation,

如果你有如下图的模型,

class Article(models.Model):
    headline = models.CharField(
        max_length=200,
        null=True,
        blank=True,
        help_text='Use puns liberally',
    )
    content = models.TextField()

您可以将标题的表单验证更改为required=True而不是blank=False,因为模型定义字段如下所示。

class ArticleForm(ModelForm):
    headline = MyFormField(
        max_length=200,
        required=False,
        help_text='Use puns liberally',
    )

    class Meta:
        model = Article
        fields = ['headline', 'content']

所以回答这个问题,

class CircuitForm(ModelForm):
    begin = forms.DateTimeField(required=False)
    end = forms.DateTimeField(required=False)
        class Meta:
            model = Circuit
            exclude = ('lastPaged',)

这使得beginend 变为required=False

【讨论】:

以上是关于模型表单中的 Django 必填字段的主要内容,如果未能解决你的问题,请参考以下文章

text ERROR DJANGO:此字段是必填项。表单向导

Django 向导表单中的条件表单字段

如何在 django 的表单中添加红色星号以显示必填字段?

如果空值传递给Django中的表单字段,如何验证表单?

使用 Django ModelForm 时标记必填字段的标签

如何在 django modelform 中的必填字段后添加 *?