0π
I may be misunderstanding your question, but I think I have a similar situation. In the dropdown you want the object to be labelled with the name of the location
. If there is a parent
for that location, you would like to show the name of that parent as well within parentheses following the location name.
You can accomplish this by overriding the __init__
method of your ModelForm:
def __init__(self, *args, **kwargs):
def new_label_from_instance(self, obj):
try:
#see if there is a parent or not
p = obj.parent
except:
#no parent; use the location's default label
rep = obj.description
return rep
#if we find a location's parent, p=parent label and d=location label
d = obj.description
rep = "%s (%s)" % (d, p)
return rep
super(PublisherCreateTSCForm, self).__init__(*args, **kwargs)
funcType = type(self.fields['location'].label_from_instance)
self.fields['location'].label_from_instance = funcType(new_label_from_instance, self.fields['location'], forms.models.ChoiceField)
You should know the consequences of doing this before you do it. Check out this old question:
Django CheckboxSelectMultiple override 'choices' from ModelForm
And the docs related to label_from_instance
here (bottom of the linked section): https://docs.djangoproject.com/en/1.7/ref/forms/fields/#modelchoicefield
1π
Finally I did this:
In the forms.py I created a method:
def get_locations_with_parents():
location_list = [(0,'Select One ...')]
locations = Position.objects.raw('select l.id, l.name, p.name as parent from locations l left join locations p on l.parent_id = p.id order by parent, l.name')
for l in locations:
if l.parent:
location = (int(l.id), l.name + " (" + l.parent + ")")
else:
location = (int(l.id), l.name)
location_list.append(location)
return tuple(location_list)
and then in the form I use
locations = forms.ChoiceField(choices=get_locations_with_parents(), validators=[validate_empty])
It does the trick and it doesnβt do 2000 queries to the DB anymore. There are some validators and clean and soβ¦ but does not really relevant to the solution.