Empty Label ChoiceField Django

后端 未结 7 927
猫巷女王i
猫巷女王i 2020-12-23 19:38

How do you make ChoiceField\'s label behave like ModelChoiceField? Is there a way to set an empty_label, or at least show a blank fiel

相关标签:
7条回答
  • 2020-12-23 20:14

    I know you already accepted an answer but I just want to post this in case someone out there runs into the issue I was having, namely the accepted solution does not work with a ValueListQuerySet. The EmptyChoiceField, which you linked to, works perfectly for me (although I am using django 1.7).

    class EmptyChoiceField(forms.ChoiceField):
        def __init__(self, choices=(), empty_label=None, required=True, widget=None, label=None, initial=None, help_text=None, *args, **kwargs):
    
            # prepend an empty label if it exists (and field is not required!)
            if not required and empty_label is not None:
                choices = tuple([(u'', empty_label)] + list(choices))
    
            super(EmptyChoiceField, self).__init__(choices=choices, required=required, widget=widget, label=label, initial=initial, help_text=help_text, *args, **kwargs) 
    
    class FilterForm(forms.ModelForm):
        #place your other fields here 
        state = EmptyChoiceField(choices=People.objects.all().values_list("state", "state").distinct(), required=False, empty_label="Show All")
    
    0 讨论(0)
  • 2020-12-23 20:14

    You can try this (assuming your choices are tuples):

    blank_choice = (('', '---------'),)
    ...
    color = forms.ChoiceField(choices=blank_choice + COLORS)
    year = forms.ChoiceField(choices=blank_choice + YEAR_CHOICES)
    

    Also, I can't tell from your code whether this is a form or a ModelForm, but it it's the latter, no need to redefine the form field here (you can include the choices=COLORS and choices=YEAR_CHOICES directly in the model field.

    Hope this helps.

    0 讨论(0)
  • 2020-12-23 20:16

    See the Django 1.11 documentation on ChoiceField. The 'empty value' for the ChoiceField is defined as the empty string '', so your list of tuples should contain a key of '' mapped to whatever value you want to show for the empty value.

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

    Note, you can avoid a form error if you want the form field to be optional by using required=False

    Also, if you already have a CHOICE_LIST without an empty value, you can insert one so it shows up first in the form drop-down menu:

    CHOICE_LIST.insert(0, ('', '----'))
    
    0 讨论(0)
  • 2020-12-23 20:16

    A little late to the party..

    How about not modifying the choices at all and just handling it with a widget?

    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
    

    Then just call it:

    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)
    

    Naturally, the EmptySelect would be placed inside some kind of common/widgets.py code and then when ever you need it, just reference it.

    0 讨论(0)
  • 2020-12-23 20:34

    Had to use 0 instead of u'' because of integer field in model. (Error was invalid literal for int() with base 10: ')

    prepend an empty label if it exists (and field is not required!)

        if not required and empty_label is not None:
            choices = tuple([(0, empty_label)] + list(choices))
    
    0 讨论(0)
  • 2020-12-23 20:36

    It is not the same form, but I did it the following way inspired by the EmptyChoiceField method:

    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
    
    0 讨论(0)
提交回复
热议问题