Django模型形式的必填字段


73

我有一个表格,其中的两个字段根据需要在我不希望出现时也出现。这是来自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()

在实际的电路模型中,字段的定义如下:

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})

我该怎么做,以便不需要这两个字段?


1
不可能通过更改窗口小部件来要求这些字段。如果模型具有(null = True,空白= True),则modelForm将其呈现为required = False。
Simplyharsh

看起来你是对的。字段本身不是必需的,但小部件中的日期和时间字段是必需的。
Ryan

Answers:


114

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

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

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

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


17

如果模型字段为blank = True,则在表单字段上将required设置为False。否则,required = True

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

看来您做对了所有事情。您可以检查的值self.fields['end'].required


请注意,某些字段(例如BooleanField)在其构造函数中具有blank = True硬编码(docs.djangoproject.com/en/dev/_modules/django/db/models/fields/…)。因此,设置blank = False将无声地失败。您必须self.fields[…].required = True在表单的构造函数中使用强制这些字段的必需行为。另请参阅code.djangoproject.com/ticket/22282
Edward D'Souza

8

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

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

如果此混入的用户也将覆盖__init__,将会发生什么?mixin仍然可以工作吗?多重继承将如何解决?
user3599803 '16

@ user3599803覆盖时,__init__您应始终致电super(),就像在我的代码段中所做的一样。
gitaarik '16

因此,如果我理解-我创建一个表单并将MyForm子类化。我从init()调用super,它将调用mixin init,但是何时调用djangl形式的init?
user3599803'7

是的,还有其他资源可以讨论此问题,如果需要,您还可以创建一个新问题,请在此处保留有关该特定问题的评论。
gitaarik '16

3

这不是一个答案,但是对于任何其他通过Google找到它的人来说,还有一点点数据:这对我来说是在带有DateField的Model Form上发生的。它必须设置为False,模型具有“ null = True,空白= 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,如本Django所建议的那样。但是,这些都不重要,因为(我猜)该模型的验证已经采用了“ to”的无效日期格式,而没有给我机会来拦截它。



0

模型领域文档中

如果您有如下所示的模型,

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',)

这使得beginendrequired=False

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.