I\'m using Django 1.0.2. I\'ve written a ModelForm backed by a Model. This model has a ForeignKey where blank=False. When Django generates HTML for this form it creates a
self.fields['xxx'].empty_value = None
would not work If you field type is TypedChoiceField
which do not have empty_label
property.
What we should do is to remove first choice:
1 . If you want to build a BaseForm
auto detect TypedChoiceField
class BaseForm(forms.ModelForm):
def __init__(self, *args, **kwargs):
super(BaseForm, 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:]
# code to process other Field
# ....
class AddClientForm(BaseForm):
pass
2.only a few form, you can use:
class AddClientForm(forms.ModelForm):
def __init__(self, *args, **kwargs):
super(AddClientForm, self).__init__(*args, **kwargs)
self.fields['xxx'].choices = self.fields['xxx'].choices[1:]
For the latest version of django the first answer should be like this
class ThingForm(models.ModelForm):
class Meta:
model = Thing
def __init__(self, *args, **kwargs):
self.base_fields['cargo'].empty_label = None
super(ThingForm, self).__init__(*args, **kwargs)`
You can use this on your model:
class MyModel(models.Model):
name = CharField('fieldname', max_length=10, default=None)
default=None is the answer :D
NOTE: I tried this on Django 1.7
Since Django 1.7, you can customize the label for the blank value by adding a value to your choices list in your model field definition. From the documentation on configuring field choices:
Unless blank=False is set on the field along with a default then a label containing "---------" will be rendered with the select box. To override this behavior, add a tuple to choices containing None; e.g. (None, 'Your String For Display'). Alternatively, you can use an empty string instead of None where this makes sense - such as on a CharField.
I checked the documentation for different versions of Django and found that this was added in Django 1.7.
This becomes more complicated when the choices are foreign keys and if you want to filter the choices based on some criteria. In such case if you set the empty_label
and then re-assign the choices (you can apply filtration here too) the empty label will be blank:
class ThingForm(models.ModelForm):
class Meta:
model = Thing
def __init__(self, *args, **kwargs):
super(ThingForm, self).__init__(*args, **kwargs)
self.fields['verb'].empty_label = None
self.fields['verb'].queryset=Verb.objects.all()
bbasically, the first line under init
can be applied for all of the fields in the form with a loop or inline loop:
def __init__(self,user, *args, **kwargs):
super(NewTicket, self).__init__(*args, **kwargs)
for f in self.fields:
self.fields[f].empty_label = None # or "Please Select" etc
See here for the complete debate on and methods for resolution of this issue.