25
Hereโs the solution that I used:
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();'}))
67
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, ('', '----'))
- [Django]-Django template system, calling a function inside a model
- [Django]-How to use MySQLdb with Python and Django in OSX 10.6?
- [Django]-Passing variable urlname to url tag in django template
8
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.
- [Django]-Django: Create fixtures without specifying a primary key?
- [Django]-Django :How to integrate Django Rest framework in an existing application?
- [Django]-How to create a Django queryset filter comparing two date fields in the same model
6
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")
- [Django]-Django package to generate random alphanumeric string
- [Django]-How to completely dump the data for Django-CMS
- [Django]-Django.db.utils.ProgrammingError: relation "bot_trade" does not exist
2
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.
- [Django]-Get all related Django model objects
- [Django]-Django's Double Underscore
- [Django]-Remove leading and trailing slash / in python
1
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))
- [Django]-Prepopulate Django (non-Model) Form
- [Django]-Best way to integrate SqlAlchemy into a Django project
- [Django]-How to force a user logout in Django?
1
another way to achieve this is to define the select widget separately from the rest of the widgets and change the method of saving the content.
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**
And in views.py you should use obj.create(**form.cleaned_data)
instead form.save()
- [Django]-"Failed building wheel for psycopg2" โ MacOSX using virtualenv and pip
- [Django]-Write only, read only fields in django rest framework
- [Django]-How can I handle Exceptions raised by dango-social-auth?
0
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
- [Django]-How does Django's nested Meta class work?
- [Django]-How to concatenate strings in django templates?
- [Django]-Django Rest Framework: Access item detail by slug instead of ID
0
Add Empty String with 9 Hyphens to choices as shown below:
class DateForm(forms.ModelForm):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
class Months(models.TextChoices):
EMPTY_LABEL = '', '---------' # Here
JANUARY = 'JAN', 'January'
FEBRUARY = 'FEB', 'February'
MARCH = 'MAR', 'March'
self.fields['month'].choices = Months.choices
- [Django]-Django, query filtering from model method
- [Django]-Heroku, postgreSQL, django, comments, tastypie: No operator matches the given name and argument type(s). You might need to add explicit type casts
- [Django]-Uninstall Django completely
0
Itโs work for me
Django version 4.0.4
Group.objects.values_list()
from django.contrib.auth.models import Group
GROUP_CHOICES = [('','Select the Group')] + list(Group.objects.values_list())
groups = forms.ChoiceField(choices=GROUP_CHOICES, required=False)
- [Django]-Django nested transactions โ โwith transaction.atomic()โ
- [Django]-Accessing the user's request in a post_save signal
- [Django]-Only accept a certain file type in FileField, server-side