Customize/remove Django select box blank option
Haven't tested this, but based on reading Django's code here and here I believe it should work:
class ThingForm(forms.ModelForm):
class Meta:
model = Thing
def __init__(self, *args, **kwargs):
super(ThingForm, self).__init__(*args, **kwargs)
self.fields['verb'].empty_label = None
EDIT: This is documented, though you wouldn't necessarily know to look for ModelChoiceField if you're working with an auto-generated ModelForm.
EDIT: As jlpp notes in his answer, this isn't complete - you have to re-assign the choices to the widgets after changing the empty_label attribute. Since that's a bit hacky, the other option that might be easier to understand is just overriding the entire ModelChoiceField:
class ThingForm(forms.ModelForm):
verb = ModelChoiceField(Verb.objects.all(), empty_label=None)
class Meta:
model = Thing
With Carl's answer as a guide and after rooting around the Django source for a couple hours I think this is the complete solution:
To remove the empty option (extending Carl's example):
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 # following line needed to refresh widget copy of choice list self.fields['verb'].widget.choices = self.fields['verb'].choices
To customize the empty option label is essentially the same:
class ThingForm(models.ModelForm): class Meta: model = Thing def __init__(self, *args, **kwargs): super(ThingForm, self).__init__(*args, **kwargs) self.fields['verb'].empty_label = "Select a Verb" # following line needed to refresh widget copy of choice list self.fields['verb'].widget.choices = self.fields['verb'].choices
I think this approach applies to all scenarios where ModelChoiceFields are rendered as HTML but I'm not positive. I found that when these fields are initialized, their choices are passed to the Select widget (see django.forms.fields.ChoiceField._set_choices). Setting the empty_label after initialization does not refresh the Select widget's list of choices. I'm not familiar enough with Django to know if this should be considered a bug.
from the docs
The blank choice will not be included if the model field has blank=False and an explicit default value (the default value will be initially selected instead).
so set the default and you're ok