1
0
mirror of https://github.com/django/django.git synced 2025-10-24 06:06:09 +00:00

Refs #19721 -- Moved ModelAdmin.list_filter docs into a separate file.

Co-authored-by: Carlton Gibson <carlton.gibson@noumenal.es>
This commit is contained in:
Shreya Bamne
2021-11-17 12:01:34 +01:00
committed by Carlton Gibson
parent 1fe23bdd29
commit e53aea2e23
2 changed files with 198 additions and 152 deletions

View File

@@ -66,6 +66,7 @@ Other topics
:maxdepth: 1
actions
filters
admindocs
javascript
@@ -853,159 +854,11 @@ subclass::
.. attribute:: 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 page of the admin.
.. image:: _images/list_filter.png
``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`` or ``ManyToManyField``, 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 the ``title`` and ``parameter_name``
attributes to and override the ``lookups`` and ``queryset`` methods,
e.g.::
from datetime import date
from django.contrib import admin
from django.utils.translation import gettext_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 the
``lookups`` and ``queryset`` methods, for example::
class AuthDecadeBornListFilter(DecadeBornListFilter):
def lookups(self, request, model_admin):
if request.user.is_superuser:
return super().lookups(request, model_admin)
def queryset(self, request, queryset):
if request.user.is_superuser:
return super().queryset(request, queryset)
Also as a convenience, the ``ModelAdmin`` object is passed to
the ``lookups`` 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 a ``ForeignKey`` to a ``User`` model, this will
limit the ``list_filter`` choices to the users who have written a book
instead of listing all users.
You can filter empty values using ``EmptyFieldListFilter``, which can
filter on both empty strings and nulls, depending on what the field
allows to store::
class BookAdmin(admin.ModelAdmin):
list_filter = (
('title', admin.EmptyFieldListFilter),
)
.. note::
The ``FieldListFilter`` API is considered internal and might be
changed.
.. note::
The :class:`~django.contrib.contenttypes.fields.GenericForeignKey`
field is not supported.
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.
At it's simplest ``list_filter`` takes a list or tuple of field names to
activate filtering upon, but several more advanced options as available.
See :ref:`modeladmin-list-filters` for the details.
.. attribute:: ModelAdmin.list_max_show_all