ModelAdmin
列表过滤器¶
ModelAdmin
类可以定义出现在管理员更改列表页面右侧边栏中的列表过滤器,如下面的屏幕截图所示

要激活每个字段的过滤,请将ModelAdmin.list_filter
设置为元素列表或元组,其中每个元素都是以下类型之一
字段名称。
django.contrib.admin.SimpleListFilter
的子类。包含字段名称和
django.contrib.admin.FieldListFilter
子类的 2 元组。
请参阅下面的示例,了解定义 list_filter
的每个选项的讨论。
使用字段名称¶
最简单的选项是指定模型中所需的字段名称。
每个指定的字段应为 BooleanField
、CharField
、DateField
、DateTimeField
、IntegerField
、ForeignKey
或 ManyToManyField
,例如
class PersonAdmin(admin.ModelAdmin):
list_filter = ["is_staff", "company"]
list_filter
中的字段名称也可以使用 __
查找跨越关系,例如
class PersonAdmin(admin.UserAdmin):
list_filter = ["company__name"]
使用 SimpleListFilter
¶
对于自定义过滤,您可以通过继承 django.contrib.admin.SimpleListFilter
来定义自己的列表过滤器。您需要提供 title
和 parameter_name
属性,并覆盖 lookups
和 queryset
方法,例如
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]
注意
为了方便起见,HttpRequest
对象被传递给 lookups
和 queryset
方法,例如
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)
同样为了方便起见,ModelAdmin
对象被传递给 lookups
方法,例如,如果您想根据可用数据来设定查找范围
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"))
使用字段名称和显式的 FieldListFilter
¶
最后,如果您希望指定一个显式的过滤器类型与字段一起使用,您可以提供一个 list_filter
项目作为 2 元组,其中第一个元素是字段名称,第二个元素是从 django.contrib.admin.FieldListFilter
继承的类,例如
class PersonAdmin(admin.ModelAdmin):
list_filter = [
("is_staff", admin.BooleanFieldListFilter),
]
这里 is_staff
字段将使用 BooleanFieldListFilter
。仅指定字段名称,字段在大多数情况下会自动使用合适的过滤器,但此格式允许您控制使用的过滤器。
以下示例显示了您需要选择使用哪些可用的过滤器类。
您可以使用 RelatedOnlyFieldListFilter
将相关模型的选择限制为该关系中涉及的对象
class BookAdmin(admin.ModelAdmin):
list_filter = [
("author", admin.RelatedOnlyFieldListFilter),
]
假设 author
是一个指向 User
模型的 ForeignKey
,这将把 list_filter
选择限制为写过书的用户,而不是列出所有用户。
您可以使用 EmptyFieldListFilter
过滤空值,它可以根据字段允许存储的内容过滤空字符串和空值
class BookAdmin(admin.ModelAdmin):
list_filter = [
("title", admin.EmptyFieldListFilter),
]
通过使用 __in
查找定义过滤器,可以过滤任何一组值。您需要覆盖 expected_parameters
方法,并使用合适的字段名称指定 lookup_kwargs
属性。默认情况下,查询字符串中的多个值将用逗号分隔,但这可以通过 list_separator
属性进行自定义。以下示例显示了使用竖线字符作为分隔符的此类过滤器
class FilterWithCustomSeparator(admin.FieldListFilter):
# custom list separator that should be used to separate values.
list_separator = "|"
def __init__(self, field, request, params, model, model_admin, field_path):
self.lookup_kwarg = "%s__in" % field_path
super().__init__(field, request, params, model, model_admin, field_path)
def expected_parameters(self):
return [self.lookup_kwarg]
注意
GenericForeignKey
字段不受支持。
列表过滤器通常仅在过滤器有多个选择时才会显示。过滤器的 has_output()
方法控制它是否显示。
可以指定自定义模板来渲染列表过滤器
class FilterWithCustomTemplate(admin.SimpleListFilter):
template = "custom_template.html"
请参阅 Django 提供的默认模板(admin/filter.html
)以获取具体示例。
方面¶
默认情况下,每个过滤器的计数(称为方面)可以通过管理员 UI 中的切换显示。这些计数将根据当前应用的过滤器进行更新。有关更多详细信息,请参阅ModelAdmin.show_facets
。