ModelAdmin
Lista Filter¶
klasserna ModelAdmin
kan definiera listfilter som visas i det högra sidofältet på sidan med ändringslistan i admin, vilket illustreras i följande skärmdump:

För att aktivera filtrering per fält anger du ModelAdmin.list_filter
till en lista eller en tupel av element, där varje element är en av följande typer:
Ett fältnamn.
En underklass av
django.contrib.admin.SimpleListFilter
.En 2-tupel som innehåller ett fältnamn och en subklass av
django.contrib.admin.FieldListFilter
.
Se exemplen nedan för en diskussion om vart och ett av dessa alternativ för att definiera list_filter
.
Använda ett fältnamn¶
Det enklaste alternativet är att ange de obligatoriska fältnamnen från din modell.
Varje angivet fält ska vara antingen en BooleanField
, CharField
, DateField
, DateTimeField
, IntegerField
, ForeignKey
eller ManyToManyField
, till exempel:
class PersonAdmin(admin.ModelAdmin):
list_filter = ["is_staff", "company"]
Fältnamn i list_filter
kan också spänna över relationer med hjälp av __
lookup, till exempel:
class PersonAdmin(admin.UserAdmin):
list_filter = ["company__name"]
Använda ett SimpleListFilter
¶
För anpassad filtrering kan du definiera ditt eget listfilter genom att underklassa django.contrib.admin.SimpleListFilter
. Du måste tillhandahålla attributen title
och parameter_name
och åsidosätta metoderna lookups
och queryset
, t.ex.:
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]
Observera
Som en bekvämlighet skickas objektet HttpRequest
till metoderna lookups
och queryset
, till exempel:
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)
Som en bekvämlighet skickas också objektet ModelAdmin
till metoden lookups
, till exempel om du vill basera uppslagningarna på tillgängliga 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"))
Använda ett fältnamn och ett explicit FieldListFilter
¶
Slutligen, om du vill ange en explicit filtertyp som ska användas med ett fält kan du tillhandahålla ett list_filter
-objekt som en 2-tupel, där det första elementet är ett fältnamn och det andra elementet är en klass som ärver från django.contrib.admin.FieldListFilter
, till exempel:
class PersonAdmin(admin.ModelAdmin):
list_filter = [
("is_staff", admin.BooleanFieldListFilter),
]
Här kommer fältet is_staff
att använda filtret BooleanFieldListFilter
. Om du bara anger fältnamnet kommer fälten automatiskt att använda lämpligt filter i de flesta fall, men med det här formatet kan du styra vilket filter som används.
Följande exempel visar tillgängliga filterklasser som du måste anmäla dig för att använda.
Du kan begränsa valen i en relaterad modell till de objekt som är involverade i den relationen med hjälp av RelatedOnlyFieldListFilter
:
class BookAdmin(admin.ModelAdmin):
list_filter = [
("author", admin.RelatedOnlyFieldListFilter),
]
Om man antar att author
är en ForeignKey
till en User
-modell, kommer detta att begränsa list_filter
-valen till de användare som har skrivit en bok, istället för att lista alla användare.
Du kan filtrera tomma värden med hjälp av EmptyFieldListFilter
, som kan filtrera på både tomma strängar och nollor, beroende på vad fältet tillåter att lagra:
class BookAdmin(admin.ModelAdmin):
list_filter = [
("title", admin.EmptyFieldListFilter),
]
Genom att definiera ett filter med hjälp av __in
lookup, är det möjligt att filtrera för något av en grupp av värden. Du måste åsidosätta metoden expected_parameters
och ange attributet lookup_kwargs
med lämpligt fältnamn. Som standard kommer flera värden i frågesträngen att separeras med kommatecken, men detta kan anpassas via attributet list_separator
. Följande exempel visar ett sådant filter som använder tecknet vertikalt rör som 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]
Observera
Fältet GenericForeignKey
stöds inte.
Listfilter visas vanligtvis bara om filtret har mer än ett val. Ett filters has_output()
-metod styr om det ska visas eller inte.
Det är möjligt att ange en anpassad mall för rendering av ett listfilter:
class FilterWithCustomTemplate(admin.SimpleListFilter):
template = "custom_template.html"
Se standardmallen som tillhandahålls av Django (admin/filter.html
) för ett konkret exempel.
Facetter¶
Som standard kan räkningar för varje filter, så kallade facetter, visas genom att slå på dem via admingränssnittet. Dessa räkningar uppdateras i enlighet med de filter som används för närvarande. Se ModelAdmin.show_facets
för mer information.