ModelAdmin.list_filter
Set list_filter
to activate filters in the right sidebar of the change list page of the admin, as illustrated in the following screenshot:
list_filter
should be a list or tuple of elements, where each element should be of one of the following types:
-
a field name, where the specified field should be either a
BooleanField
,CharField
,DateField
,DateTimeField
,IntegerField
,ForeignKey
orManyToManyField
, for example:class PersonAdmin(admin.ModelAdmin): list_filter = ('is_staff', 'company')
Field names in
list_filter
can also span relations using the__
lookup, for example:class PersonAdmin(admin.UserAdmin): list_filter = ('company__name',)
-
a class inheriting from
django.contrib.admin.SimpleListFilter
, which you need to provide thetitle
andparameter_name
attributes to and override thelookups
andqueryset
methods, e.g.:from datetime import date from django.contrib import admin from django.utils.translation import ugettext_lazy as _ class DecadeBornListFilter(admin.SimpleListFilter): # Human-readable title which will be displayed in the # right admin sidebar just above the filter options. title = _('decade born') # Parameter for the filter that will be used in the URL query. parameter_name = 'decade' def lookups(self, request, model_admin): """ Returns a list of tuples. The first element in each tuple is the coded value for the option that will appear in the URL query. The second element is the human-readable name for the option that will appear in the right sidebar. """ return ( ('80s', _('in the eighties')), ('90s', _('in the nineties')), ) def queryset(self, request, queryset): """ Returns the filtered queryset based on the value provided in the query string and retrievable via `self.value()`. """ # Compare the requested value (either '80s' or '90s') # to decide how to filter the queryset. if self.value() == '80s': return queryset.filter(birthday__gte=date(1980, 1, 1), birthday__lte=date(1989, 12, 31)) if self.value() == '90s': return queryset.filter(birthday__gte=date(1990, 1, 1), birthday__lte=date(1999, 12, 31)) class PersonAdmin(admin.ModelAdmin): list_filter = (DecadeBornListFilter,)
Note
As a convenience, the
HttpRequest
object is passed to thelookups
andqueryset
methods, for example:class AuthDecadeBornListFilter(DecadeBornListFilter): def lookups(self, request, model_admin): if request.user.is_superuser: return super(AuthDecadeBornListFilter, self).lookups(request, model_admin) def queryset(self, request, queryset): if request.user.is_superuser: return super(AuthDecadeBornListFilter, self).queryset(request, queryset)
Also as a convenience, the
ModelAdmin
object is passed to thelookups
method, for example if you want to base the lookups on the available data:class AdvancedDecadeBornListFilter(DecadeBornListFilter): def lookups(self, request, model_admin): """ Only show the lookups if there actually is anyone born in the corresponding decades. """ qs = model_admin.get_queryset(request) if qs.filter(birthday__gte=date(1980, 1, 1), birthday__lte=date(1989, 12, 31)).exists(): yield ('80s', _('in the eighties')) if qs.filter(birthday__gte=date(1990, 1, 1), birthday__lte=date(1999, 12, 31)).exists(): yield ('90s', _('in the nineties'))
-
a tuple, where the first element is a field name and the second element is a class inheriting from
django.contrib.admin.FieldListFilter
, for example:class PersonAdmin(admin.ModelAdmin): list_filter = ( ('is_staff', admin.BooleanFieldListFilter), )
You can limit the choices of a related model to the objects involved in that relation using
RelatedOnlyFieldListFilter
:class BookAdmin(admin.ModelAdmin): list_filter = ( ('author', admin.RelatedOnlyFieldListFilter), )
Assuming
author
is aForeignKey
to aUser
model, this will limit thelist_filter
choices to the users who have written a book instead of listing all users.Note
The
FieldListFilter
API is considered internal and might be changed.
List filter’s typically appear only if the filter has more than one choice. A filter’s has_output()
method controls whether or not it appears.
It is possible to specify a custom template for rendering a list filter:
class FilterWithCustomTemplate(admin.SimpleListFilter): template = "custom_template.html"
See the default template provided by django (admin/filter.html
) for a concrete example.
Please login to continue.