I have a django application which has two models like this:
class MyModel(models.Model):
name = models.CharField()
country = models.ForeignKey(\'Coun
This is my take on a general and reusable implementation for Django 1.4, if you happen to be stuck at that version. It is inspired by the built-in version that is now part of Django 1.8 and upwards. Also, it should be quite a small task to adapt it to 1.5–1.7, mainly the queryset methods have changed name in those. I've put the filter itself in a core application that I have but you can obviously put it anywhere.
Implementation:
# myproject/core/admin/filters.py:
from django.contrib.admin.filters import RelatedFieldListFilter
class RelatedOnlyFieldListFilter(RelatedFieldListFilter):
def __init__(self, field, request, params, model, model_admin, field_path):
self.request = request
self.model_admin = model_admin
super(RelatedOnlyFieldListFilter, self).__init__(field, request, params, model, model_admin, field_path)
def choices(self, cl):
limit_choices_to = set(self.model_admin.queryset(self.request).values_list(self.field.name, flat=True))
self.lookup_choices = [(pk_val, val) for pk_val, val in self.lookup_choices if pk_val in limit_choices_to]
return super(RelatedOnlyFieldListFilter, self).choices(cl)
Usage:
# myapp/admin.py:
from django.contrib import admin
from myproject.core.admin.filters import RelatedOnlyFieldListFilter
from myproject.myapp.models import MyClass
class MyClassAdmin(admin.ModelAdmin):
list_filter = (
('myfield', RelatedOnlyFieldListFilter),
)
admin.site.register(MyClass, MyClassAdmin)
If you later update to Django 1.8 you should be able to just change this import:
from myproject.core.admin.filters import RelatedOnlyFieldListFilter
To this:
from django.contrib.admin.filters import RelatedOnlyFieldListFilter