Limit foreign key choices in select in an inline form in admin
Used request instance as temporary container for obj.Overrided Inline method formfield_for_foreignkey to modify queryset.This works at least on django 1.2.3.
class RoomInline(admin.TabularInline): model = Room def formfield_for_foreignkey(self, db_field, request=None, **kwargs): field = super(RoomInline, self).formfield_for_foreignkey(db_field, request, **kwargs) if db_field.name == 'inside_room': if request._obj_ is not None: field.queryset = field.queryset.filter(building__exact = request._obj_) else: field.queryset = field.queryset.none() return fieldclass BuildingAdmin(admin.ModelAdmin): inlines = (RoomInline,) def get_form(self, request, obj=None, **kwargs): # just save obj reference for future processing in Inline request._obj_ = obj return super(BuildingAdmin, self).get_form(request, obj, **kwargs)
After reading through this post and experimenting a lot I think I have found a rather definitive answer to this question. As this is a design pattern that is ofter used I have written a Mixin for the Django admin to make use of it.
(Dynamically) limiting the queryset for ForeignKey fields is now as simple as subclassing LimitedAdminMixin
and defining a get_filters(obj)
method to return the relevant filters. Alternateively, a filters
property can be set on the admin if dynamic filtering is not required.
Example usage:
class MyInline(LimitedAdminInlineMixin, admin.TabularInline): def get_filters(self, obj): return (('<field_name>', dict(<filters>)),)
Here, <field_name>
is the name of the FK field to be filtered and <filters>
is a list of parameters as you would normally specify them in the filter()
method of querysets.
There is limit_choices_to ForeignKey option that allows to limit the available admin choices for the object