# Django 6.0.5 documentation

# `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.