Reputation: 30218
I have a ModelForm
where one of the field (named creator
) is a ForeignKey
, so for {{ form.creator }}
Django renders the <select>
tag like this:
<select id="id_approver" name="approver">
<option selected="selected" value="">---------</option>
<option value="1">hobbes3</option>
<option value="2">tareqmd</option>
<option value="3">bob</option>
<option value="4">sam</option>
<option value="5">jane</option>
</select>
But I want to add a onchange
event attribute so I can use AJAX later to do something else. I also want to change ---------
to say something else and display the approvers' full name, not their username.
So is it possible to get a list of possible approvers and generate my own select options? Kind of like
<select id="id_approver" name="approver" onchange="some_ajax_function()">
<option select="selected" value="0">Choose a user</option>
{% for approver in form.approver.all %} <!-- This won't work -->
<option value="{{ approver.pk }}">{{ approver.get_full_name }}</option>
{% endfor %}
</select>
And I'm also thinking most of the list of approvers get too large (like over 50), then I'll eventually want some sort of a searchable auto-complete field for the approver. So then I'll definitely need to write my own HTML.
In case anyone needs it, my ModelForm
looks like this:
class OrderCreateForm( ModelForm ) :
class Meta :
model = Order
fields = (
'creator',
'approver',
'work_type',
'comment',
)
Upvotes: 2
Views: 5012
Reputation: 174614
The ModelChoiceField documentation explains how to do this.
To change the empty label:
empty_label
By default the <select> widget used by ModelChoiceField
will have an empty choice at the top of the list. You can change the text
of this label (which is "---------" by default) with the empty_label
attribute, or you can disable the empty label entirely by setting
empty_label to None:
# A custom empty label
field1 = forms.ModelChoiceField(queryset=..., empty_label="(Nothing)")
# No empty label
field2 = forms.ModelChoiceField(queryset=..., empty_label=None)
As for your second query, it is also explained the in docs:
The __unicode__ method of the model will be called to generate string
representations of the objects for use in the field's choices;
to provide customized representations, subclass ModelChoiceField and override
label_from_instance. This method will receive a model object, and should return
a string suitable for representing it. For example:
class MyModelChoiceField(ModelChoiceField):
def label_from_instance(self, obj):
return "My Object #%i" % obj.id
Finally, to pass some custom ajax, use the attrs
argument for the select widget (which is what is used in the ModelForm field).
In the end, you should have something like this:
creator = MyCustomField(queryset=...,
empty_label="Please select",
widget=forms.Select(attrs={'onchange':'some_ajax_function()'})
Upvotes: 1