空标签ChoiceField Django

空标签ChoiceField Django,django,forms,label,Django,Forms,Label,如何使ChoiceField的标签的行为类似于ModelChoiceField?有没有办法设置一个空标签,或者至少显示一个空白字段 Forms.py: thing = forms.ModelChoiceField(queryset=Thing.objects.all(), empty_label='Label') color = forms.ChoiceField(choices=COLORS) year = forms.ChoiceField(choices=YEAR_

如何使
ChoiceField
的标签的行为类似于
ModelChoiceField
?有没有办法设置一个
空标签
,或者至少显示一个空白字段

Forms.py:

    thing = forms.ModelChoiceField(queryset=Thing.objects.all(), empty_label='Label')
    color = forms.ChoiceField(choices=COLORS)
    year = forms.ChoiceField(choices=YEAR_CHOICES)

我尝试过这里建议的解决方案:

-设置
CHOICES=[('','All')]+CHOICES
导致内部服务器错误

-在“我的选择”中定义了
('','-----------'),
后,仍然默认为列表中的第一项,而不是
('','-----------'),
选择

-尝试使用此处定义的
EmptyChoiceField
,但使用Django 1.4无效

但是这些对我都不起作用。。你将如何解决这个问题?谢谢你的想法

您可以试试这个(假设您的选择是元组):

另外,我无法从您的代码中判断这是表单还是模型表单,但它是后者,不需要在这里重新定义表单字段(您可以在模型字段中直接包含选项=颜色和选项=年份)


希望这能有所帮助。

请参阅上的Django 1.11文档。ChoiceField的“空值”定义为空字符串
'
,因此元组列表应包含一个
'
键,该键映射到要为空值显示的任何值

### forms.py
from django.forms import Form, ChoiceField

CHOICE_LIST = [
    ('', '----'), # replace the value '----' with whatever you want, it won't matter
    (1, 'Rock'),
    (2, 'Hard Place')
]

class SomeForm (Form):

    some_choice = ChoiceField(choices=CHOICE_LIST, required=False)
注意,如果希望表单字段是可选的,可以通过使用
required=False

此外,如果您已经有一个选项列表,但没有空值,则可以插入一个选项列表,使其首先显示在表单下拉菜单中:

CHOICE_LIST.insert(0, ('', '----'))

以下是我使用的解决方案:

from myapp.models import COLORS

COLORS_EMPTY = [('','---------')] + COLORS

class ColorBrowseForm(forms.Form):
    color = forms.ChoiceField(choices=COLORS_EMPTY, required=False, widget=forms.Select(attrs={'onchange': 'this.form.submit();'}))

我知道你已经接受了一个答案,但我只是想发布这篇文章,以防有人遇到我遇到的问题,即接受的解决方案不适用于ValueListQuerySet。你链接到的,非常适合我(尽管我使用的是django 1.7)

由于模型中的整型字段,必须使用0而不是u“”。(错误对于以10为基数的int()而言是无效的文本:')

如果存在空标签(且字段不是必需的),则在其前面加上空标签 晚会有点晚了

不修改选择,只使用小部件处理它怎么样

from django.db.models import BLANK_CHOICE_DASH

class EmptySelect(Select):
    empty_value = BLANK_CHOICE_DASH[0]
    empty_label = BLANK_CHOICE_DASH[1]

    @property
    def choices(self):
        yield (self.empty_value, self.empty_label,)
        for choice in self._choices:
            yield choice

    @choices.setter
    def choices(self, val):
        self._choices = val
那就叫它:

class SomeForm(forms.Form):
    # thing = forms.ModelChoiceField(queryset=Thing.objects.all(), empty_label='Label')
    color = forms.ChoiceField(choices=COLORS, widget=EmptySelect)
    year = forms.ChoiceField(choices=YEAR_CHOICES, widget=EmptySelect)

当然,
EmptySelect
会被放置在某种
公共/widgets.py
代码中,然后在需要时,只需引用它。

它不是同一种形式,但受EmptyChoiceField方法的启发,我采用了以下方法:

from django import forms
from ..models import Operator


def parent_operators():
    choices = Operator.objects.get_parent_operators().values_list('pk', 'name')
    choices = tuple([(u'', 'Is main Operator')] + list(choices))
    return choices


class OperatorForm(forms.ModelForm):
    class Meta:
        model = Operator
        # fields = '__all__'
        fields = ('name', 'abbr', 'parent', 'om_customer_id', 'om_customer_name', 'email', 'status')

    def __init__(self, *args, **kwargs):
        super(OperatorForm, self).__init__(*args, **kwargs)
        self.fields['name'].widget.attrs.update({'class': 'form-control m-input form-control-sm'})
        self.fields['abbr'].widget.attrs.update({'class': 'form-control m-input form-control-sm'})
        self.fields['parent'].widget.attrs.update({'class': 'form-control m-input form-control-sm'})
        self.fields['parent'].choices = parent_operators()
        self.fields['parent'].required = False
        self.fields['om_customer_id'].widget.attrs.update({'class': 'form-control m-input form-control-sm'})
        self.fields['om_customer_name'].widget.attrs.update({'class': 'form-control m-input form-control-sm'})
        self.fields['email'].widget.attrs.update({'class': 'form-control m-input form-control-sm', 'type': 'email'})enter code here

实现这一点的另一种方法是将select小部件与其他小部件分开定义,并更改保存内容的方法

forms.py

class CardAddForm(forms.ModelForm):
    category = forms.ModelChoiceField(empty_label='Choose category',
                                      queryset=Categories.objects.all(),
                                      widget=forms.Select(attrs={'class':'select-css'}))

    class Meta:
        **other model field**

views.py中,您应该使用
obj.create(**form.cleaned_data)
而不是
form.save()

尝试将其与ModelForm一起使用会导致:
TypeError:只能将元组(而不是“list”)连接到元组
@NickB,那么您的选择不是元组,所以您需要空白的选择=[('''''.---')]你找到解决这个问题的方法了吗?嗨@Amyth,看到我发布的答案了。我能用(None,“----”)代替(“----”)?我询问的原因是以前我没有空白条目,如果用户没有进行选择,我没有收到任何信息。通过该更改,我收到了“”,现在我收到了大量的if语句fails@Johan:是,无以
形式传输。如果选择来自元组值
(无,'-')
。有人能谈谈空字符串值对平均值和其他数字计算的影响吗?如果颜色是一个元组,则不能向其中添加列表。如果将颜色声明为元组的元组,最好的方法是reczy所说的。blank_choice=(“”,--------------’),)blank_choice+colors这是一个很好的解决方案。Django 3.0的更新:EmptyChoice字段类的最后一行应该以super()开头。_uuuinit_uuu(choices=…并且可以完全去掉*args
class SomeForm(forms.Form):
    # thing = forms.ModelChoiceField(queryset=Thing.objects.all(), empty_label='Label')
    color = forms.ChoiceField(choices=COLORS, widget=EmptySelect)
    year = forms.ChoiceField(choices=YEAR_CHOICES, widget=EmptySelect)
from django import forms
from ..models import Operator


def parent_operators():
    choices = Operator.objects.get_parent_operators().values_list('pk', 'name')
    choices = tuple([(u'', 'Is main Operator')] + list(choices))
    return choices


class OperatorForm(forms.ModelForm):
    class Meta:
        model = Operator
        # fields = '__all__'
        fields = ('name', 'abbr', 'parent', 'om_customer_id', 'om_customer_name', 'email', 'status')

    def __init__(self, *args, **kwargs):
        super(OperatorForm, self).__init__(*args, **kwargs)
        self.fields['name'].widget.attrs.update({'class': 'form-control m-input form-control-sm'})
        self.fields['abbr'].widget.attrs.update({'class': 'form-control m-input form-control-sm'})
        self.fields['parent'].widget.attrs.update({'class': 'form-control m-input form-control-sm'})
        self.fields['parent'].choices = parent_operators()
        self.fields['parent'].required = False
        self.fields['om_customer_id'].widget.attrs.update({'class': 'form-control m-input form-control-sm'})
        self.fields['om_customer_name'].widget.attrs.update({'class': 'form-control m-input form-control-sm'})
        self.fields['email'].widget.attrs.update({'class': 'form-control m-input form-control-sm', 'type': 'email'})enter code here
class CardAddForm(forms.ModelForm):
    category = forms.ModelChoiceField(empty_label='Choose category',
                                      queryset=Categories.objects.all(),
                                      widget=forms.Select(attrs={'class':'select-css'}))

    class Meta:
        **other model field**