Django,如何删除modelform中choicefield的空白选项?

pxyaymoc  于 2023-01-14  发布在  Go
关注(0)|答案(6)|浏览(116)

我创建了一个包含外键的模型:

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

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

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

当我显示带有表单的页面时,我得到了Library选项,但也得到了默认情况下的空白(--------)选项。
我以为通过在模型中设置null=False和blank=False,可以消除ModelForm中的空白选择,但是没有。要使列表中只有实际的选择而没有那个选择,我该怎么做呢?

kg7wmglp

kg7wmglp1#

请参见ModelChoiceField。您必须将empty_label设置为None。因此,您的代码将类似于:

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

    class Meta:
        model = Book

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

ryoqjall

ryoqjall2#

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:]
ppcbkaq5

ppcbkaq53#

如果使用ModelForm,则不必指定queryset、required、label等。但是对于投票通过的答案,则必须再次指定。
实际上,这样做可以避免重新指定所有内容

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

    class Meta:
        model = Book
svdrlsy4

svdrlsy44#

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

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

bvn4nwqk5#

只需转到您的选择列表(假设您已将其设为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,您将告诉选择字段默认为某个字符串。如果您不想默认为任何值,只需将''放入空括号中。

ivqmmu1c

ivqmmu1c6#

对于那些正在尝试上述解决方案但无法使其工作的人,我通过提供自己的custom CSS to my forms subclass使其工作。

/* STATICFILES_DIRS/css/my_customizations.css */
#id_field_name li:has(input[value='']) {
  visibility: hidden;
  padding: 0;
  margin: 0;
  height: 0;
}
from django import forms

from .models import MyModel

class MyForm(
    forms.modelform_factory(
        MyModel,
        widgets={"field_name": forms.RadioSelect(attrs={"class": "inline li"})},
        fields="__all__",
    )
):
    class Media:
        css = {"all": ("css/my_customizations.css",)}

这使我可以在数据库中初始化该选项为null,但要确保编写者选择这两个字段中的一个,并且不将其从有效值更改为未设置的值。
尽管截至2023年1月,Firefox还不支持:has,但有望在今年的某个时候支持。

相关问题