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:12class
PersonAdmin(admin.ModelAdmin):
list_filter
=
(
'is_staff'
,
'company'
)
Field names in
list_filter
can also span relations using the__
lookup, for example:12class
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.:12345678910111213141516171819202122232425262728293031323334353637383940414243from
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:123456789class
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:1234567891011121314class
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:1234class
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
:1234class
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:
1 2 | 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.