I found a pretty elegant solution that works well for inline forms.
Applies to my model, where I filter the inside_room field to only return rooms that are in the same building:
#spaces/admin.py class RoomInlineForm(ModelForm): def __init__(self, *args, **kwargs): super(RoomInlineForm, self).__init__(*args, **kwargs) #On init... if 'instance' in kwargs: building = kwargs['instance'].building else: building_id = tuple(i[0] for i in self.fields['building'].widget.choices)[1] building = Building.objects.get(id=building_id) self.fields['inside_room'].queryset = Room.objects.filter(building__exact=building)
Basically, if the keyword "instance" is passed to the form, it is an existing entry displayed in the inline string, and so I can just grab the building from the instance. If this is not an instance, it is one of the empty extra lines in the line, and therefore it goes through the hidden fields of the embedded line form, which save the implicit relation back to the main page and grab the id value from it. Then it captures the building object based on this building_id. Finally, now that we have the building, we can set up a set of queries for the drop-down lists to display only the corresponding elements.
More elegant than my original solution, which crashed and burned as a built-in (but it worked - well, if you do not mind saving the form partially to fill in the drop-downs - for individual forms):
class RoomForm(forms.ModelForm):
For non-inlines, it worked if a room already existed. If this is not the case, it will cause an error (DoNotExist), so I will catch it and then hide the field (since there was no way from the administrator to restrict it to the desired building, since the entire room number was new and no building was installed yet!) ... as soon as you click "Save", it will save the building and reload it to limit the choice ...
I just need to find a way to cascade foreign key filters from one field to another in a new record - that is, a new record, select the building and automatically limit the selection in the selection box inside the message - until the record is saved. But this is the next day ...
mightyhal Dec 09 '09 at 2:39 2009-12-09 02:39
source share