【问题标题】:Django, how to remove the blank choice from the choicefield in modelform?Django,如何从模型表单的选择字段中删除空白选择?
【发布时间】: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 中的空白选择,但没有。我该怎么做才能在列表中只有实际选择而不是那个?

【问题讨论】:

    标签: django forms


    【解决方案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,您告诉选择字段默认为某个字符串。如果您想默认为空,只需将'' 放在空括号中即可。

    【讨论】:

    • 当性别和性取向在您的新约会应用中发生正面冲突时
    猜你喜欢
    • 2017-07-31
    • 1970-01-01
    • 1970-01-01
    • 2018-11-04
    • 2013-01-07
    • 1970-01-01
    • 2019-10-06
    • 1970-01-01
    • 2012-04-20
    相关资源
    最近更新 更多