Reputation: 43
Django docs say when using ModelChoiceField on a form and form is set to required=False and model is set to blank=True in addition to no default values, then I should receive a free empty choice within my select tag. I am not. Any ideas to what I've done to lose the empty choice?
class Location(models.Model):
location_name = models.CharField(max_length=50, blank=True)
address = models.CharField(max_length=50)
active = models.BooleanField(default=True)
def __unicode__(self):
return self.location_name
class CalcForm(forms.Form):
startAddr = forms.ModelChoiceField(queryset=Location.objects.all(), required=False)
waypoint1 = forms.ModelChoiceField(queryset=Location.objects.all(), required=False)
waypoint2 = forms.ModelChoiceField(queryset=Location.objects.all(), required=False)
...
endAddr = forms.ModelChoiceField(queryset=Location.objects.all(), required=False)
<form action="../calcview" method="get">{% csrf_token% }
<label>
<div>Start Address</div>
<select name="startAddr">
{% for location in form.fields.startAddr.queryset %}
<option value = "{ location.location_name }">{{location.location_name}}/option>
{% end for %}
</select>
...
</form>
Upvotes: 3
Views: 8135
Reputation: 188
You can use the empty_label
on your ModelChoiceField
.
startAddr = forms.ModelChoiceField(empty_label='---------', queryset=Location.objects.all(), required=False)
Then render the form field into the template.
{{ form.startAddr }}
https://docs.djangoproject.com/en/2.1/ref/forms/fields/#django.forms.ModelChoiceField.empty_label
Upvotes: 4
Reputation: 684
I know, you asked more than half a year ago, but I thought I post another answer anyway. Because I think there is a more elegant solution that uses the "empty_label
" that you can define in your form.
You can access this empty_label attribute through form.fields.startAddr.empty_label
or form.startAddr.field.empty_label
in your template. So you can include it like this:
<select id="{{ form.fields.startAddr.id_for_label }}" name="{{ form.fields.startAddr.html_name }}">
<option value="">{{ form.fields.startAddr.empty_label }}</option>
{% for location in form.fields.startAddr.queryset %}
<option value="{{ location.location_name }}">{{ location.location_name }}/option>
{% endfor %}
</select>
I wonder if you did not actually want to use {{ location.id }}
as value? Or is the location_name
unique? As it could even be empty, the auto-generated id
might be better as a reference.
As you can see, I have also replaced name="startAddr"
with information the form object provides anyway for every field: id="{{ form.fields.startAddr.id_for_label }}" name="{{ form.fields.startAddr.html_name }}
. Using these variables should make your template code more flexible and robust.
For more details, please check the Django documentation:
Upvotes: 1
Reputation: 16806
You will only get the 'free' empty option if you allow django forms to render the form field automatically. Because you are rendering it yourself in your template (and I don't know why you would want to do that...) you would need to add the empty select yourself:
<select name="startAddr">
<option value="">-----------</option>
{% for location in form.fields.startAddr.queryset %}
<option value = "{ location.location_name }">{{location.location_name}}</option>
{% end for %}
</select>
You can test this by allowing django form to render it for you:
<div>Start Address</div>
{{ form.startAddr }}
Upvotes: 5