Django,如何从模型表单的选择字段中删除空白选择?

Posted

技术标签:

【中文标题】Django,如何从模型表单的选择字段中删除空白选择?【英文标题】:Django, how to remove the blank choice from the choicefield in modelform? 【发布时间】:2012-02-06 14:21:39 【问题描述】:

我创建了一个带有外键的模型:

class Book(models.Model):
    library = models.ForeignKey(Library, null=False, blank=False)
    ...

然后我创建了一个带有 ModelForm 的表单来显示给用户:

class BookSubmitForm(ModelForm):
    class Meta:
        model = Book

当我使用表单显示页面时,我会得到库选项,但也会得到默认的空白 (--------) 选项。

我认为通过在模型中使用 null=False 和 blank=False 可以摆脱 ModelForm 中的空白选择,但没有。我该怎么做才能在列表中只有实际选择而不是那个?

【问题讨论】:

【参考方案1】:

见ModelChoiceField。您必须将 empty_label 设置为 None。所以你的代码会是这样的:

class BookSubmitForm(ModelForm):
    library = ModelChoiceField(queryset=Library.objects, empty_label=None)

    class Meta:
        model = Book    

编辑:将字段名称更改为小写

【讨论】:

它有点工作,但我仍然在表单中看到原始的 ChoiceField 带有空白选项,旁边是具有相同标签和相同选项但没有空白选项的新选项。看起来这个方法并没有覆盖表单,而是用相同的字段扩展它。 好吧,我错了,这是一个错字,我使用了一个大写的第一个字母,就像你的例子“图书馆”一样。当切换到小写“库”时,它实际上会覆盖该字段。谢谢! 太棒了!如果您不打算更改查询集,也可以简单地 self.fields['library'].empty_label = None【参考方案2】:

self.fields['xxx'].empty_label = None 将不起作用如果您的字段类型是 TypedChoiceField 没有 empty_label 属性。 我们应该做的是删除第一选择:

class BookSubmitForm(forms.ModelForm):

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

        for field_name in self.fields:
            field = self.fields.get(field_name)
            if field and isinstance(field , forms.TypedChoiceField):
                field.choices = field.choices[1:]

【讨论】:

仅当您无法为模型中的字段设置默认值时才使用此选项,这是一种更简洁的选择(请参阅 Daniel Sokolowski 的回答)。【参考方案3】:

如果您使用 ModelForm,那么您不必指定查询集、必填项、标签等。但对于获得投票的答案,您必须再次执行。

实际上你可以这样做以避免重新指定所有内容

class BookSubmitForm(ModelForm):
    def __init__(self, *args, **kwargs):
        super(BookSubmitForm, self).__init__(*args, **kwargs)
        self.fields['library'].empty_label = None

    class Meta:
        model = Book 

【讨论】:

不知何故这对我不起作用。如果如上所述设置 empty_label = None,我仍然将“---------”视为选项之一。这对 Django 1.10 仍然有效吗? 实际上,我认为这是一个 TypedChoiceField ,因此下面@Mithril 的回答有效。【参考方案4】:

如果你在模型字段定义上指定blank=Falsedefault=<VALUE>,那么默认情况下Django 不会呈现空白选项;请注意,默认值可能是无效的选择,例如设置为'' 或任何invalid choice

class Book(models.Model):
    library = models.ForeignKey(Library, null=False, blank=False, default='')
    ...

【讨论】:

仅仅为了适应表格而改变模型似乎是不对的。仅当您的模型以这种方式运行时才应该这样做。【参考方案5】:

只需转到您的选择列表(假设您已将其设为 CharField)并为 None 提供以下代码:

另外,请记住,这是一个示例,与相关代码无关。它只是为了帮助任何为默认选项而苦苦挣扎的人。

GENDER_CHOICES = (
    (None, 'Sex:'),
    ('M', 'Male'),
    ('F', 'Female'),
    ('G', 'Gay'),
    ('L', 'Lesbian'),
    ('B', 'Bi'),
    ('O', 'Other')
)
Choose_gender = models.CharField(max_length=1, choices=GENDER_CHOICES, blank=True)

通过指定None,您告诉选择字段默认为某个字符串。如果您想默认为空,只需将'' 放在空括号中即可。

【讨论】:

当性别和性取向在您的新约会应用中发生正面冲突时

以上是关于Django,如何从模型表单的选择字段中删除空白选择?的主要内容,如果未能解决你的问题,请参考以下文章

如何在没有模型的 Django 表单中设置空白=假

如何从 Django 表单中删除必需的属性

自定义/删除 Django 选择框空白选项

jquery:如何在提交之前从表单中删除空白字段?

如何使用 django 表单/模型来表示字段之间的选择?

Django:如何在手动表单字段中显示模型的外键对象作为选择