# Django 6.0.7 documentation

# Ansvariga

class Manager

En `Manager` är det gränssnitt genom vilket databasfrågeoperationer tillhandahålls till Django-modeller. Det finns minst en `Manager` för varje modell i en Django-applikation.

Hur klasserna `Manager` fungerar finns dokumenterat i Göra förfrågningar; detta dokument tar specifikt upp modellalternativ som anpassar `Manager` beteende.

## Namn på chefer

Som standard lägger Django till en `Manager` med namnet `objects` till varje Django modellklass. Men om du vill använda `objects` som fältnamn, eller om du vill använda ett annat namn än `objects` för `Manager`, kan du byta namn på den per modell. Om du vill byta namn på `Manager` för en viss klass definierar du ett klassattribut av typen `models.Manager()` för den modellen. Till exempel:

    from django.db import models

    class Person(models.Model):
        # ...
        people = models.Manager()

Med hjälp av denna exempelmodell kommer `Person.objects` att generera ett `AttributeError` undantag, men `Person.people.all()` kommer att ge en lista över alla `Person` objekt.

## Anpassade chefer

Du kan använda en anpassad `Manager` i en viss modell genom att utöka basklassen `Manager` och instansiera din anpassade `Manager` i din modell.

Det finns två anledningar till att du vill anpassa en `Manager`: att lägga till extra `Manager`-metoder och/eller att ändra den första `QuerySet` som `Manager` returnerar.

### Lägga till extra förvaltningsmetoder

Att lägga till extra `Manager`-metoder är det bästa sättet att lägga till funktionalitet på ”tabellnivå” i dina modeller. (För funktioner på ”radnivå”, dvs. funktioner som verkar på en enda instans av ett modellobjekt, ska du använda Model methods, inte anpassade `Manager`-metoder)

Till exempel lägger den här anpassade `Manager` till en metod `with_counts()`:

    from django.db import models
    from django.db.models.functions import Coalesce

    class PollManager(models.Manager):
        def with_counts(self):
            return self.annotate(num_responses=Coalesce(models.Count("response"), 0))

    class OpinionPoll(models.Model):
        question = models.CharField(max_length=200)
        objects = PollManager()

    class Response(models.Model):
        poll = models.ForeignKey(OpinionPoll, on_delete=models.CASCADE)
        # ...

I det här exemplet skulle du använda `OpinionPoll.objects.with_counts()` för att få en `QuerySet` av `OpinionPoll`-objekt med det extra attributet `num_responses`.

En anpassad `Manager`-metod kan returnera vad du vill. Den behöver inte returnera en `QuerySet`.

En annan sak att notera är att `Manager`-metoder kan komma åt `self.model` för att hämta den modellklass som de är kopplade till.

### Ändra en chefs initiala `QuerySet`

En `Manager`’s bas `QuerySet` returnerar alla objekt i systemet. Till exempel, med hjälp av denna modell:

    from django.db import models

    class Book(models.Model):
        title = models.CharField(max_length=100)
        author = models.CharField(max_length=50)

…kommer uttalandet `Book.objects.all()` att returnera alla böcker i databasen.

Du kan åsidosätta en `Manager`’s bas `QuerySet` genom att åsidosätta metoden `Manager.get_queryset()`. `get_queryset()` bör returnera en `QuerySet` med de egenskaper du behöver.

Till exempel har följande modell två `Manager` - en som returnerar alla objekt och en som bara returnerar böckerna av Roald Dahl:

    # First, define the Manager subclass.
    class DahlBookManager(models.Manager):
        def get_queryset(self):
            return super().get_queryset().filter(author="Roald Dahl")

    # Then hook it into the Book model explicitly.
    class Book(models.Model):
        title = models.CharField(max_length=100)
        author = models.CharField(max_length=50)

        objects = models.Manager()  # The default manager.
        dahl_objects = DahlBookManager()  # The Dahl-specific manager.

Med den här exempelmodellen kommer `Book.objects.all()` att returnera alla böcker i databasen, men `Book.dahl_objects.all()` kommer bara att returnera de som är skrivna av Roald Dahl.

Eftersom `get_queryset()` returnerar ett `QuerySet`-objekt kan du använda `filter()`, `exclude()` och alla andra `QuerySet`-metoder på det. Så dessa uttalanden är alla lagliga:

    Book.dahl_objects.all()
    Book.dahl_objects.filter(title="Matilda")
    Book.dahl_objects.count()

Detta exempel visade också på en annan intressant teknik: att använda flera managers på samma modell. Du kan koppla så många `Manager()`-instanser till en modell som du vill. Detta är ett icke-repetitivt sätt att definiera gemensamma ”filter” för dina modeller.

Till exempel:

    class AuthorManager(models.Manager):
        def get_queryset(self):
            return super().get_queryset().filter(role="A")

    class EditorManager(models.Manager):
        def get_queryset(self):
            return super().get_queryset().filter(role="E")

    class Person(models.Model):
        first_name = models.CharField(max_length=50)
        last_name = models.CharField(max_length=50)
        role = models.CharField(max_length=1, choices={"A": _("Author"), "E": _("Editor")})
        people = models.Manager()
        authors = AuthorManager()
        editors = EditorManager()

I det här exemplet kan du begära `Person.authors.all()`, `Person.editors.all()` och `Person.people.all()`, vilket ger förutsägbara resultat.

### Förvaltare som standard

Model._default_manager

Om du använder anpassade `Manager`-objekt, notera att den första `Manager` som Django stöter på (i den ordning de definieras i modellen) har en speciell status. Django tolkar den första `Manager` som definieras i en klass som ”standard” `Manager`, och flera delar av Django (inklusive `dumpdata`) kommer att använda den `Manager` exklusivt för den modellen. Som ett resultat är det en bra idé att vara försiktig i ditt val av standardhanterare för att undvika en situation där åsidosättande av `get_queryset()` resulterar i en oförmåga att hämta objekt som du vill arbeta med.

Du kan ange en anpassad standardhanterare med `Meta.default_manager_name <django.db.models.Options.default_manager_name>``.

Om du skriver kod som måste hantera en okänd modell, t.ex. i en tredjepartsapp som implementerar en generisk vy, ska du använda den här hanteraren (eller `_base_manager`) i stället för att anta att modellen har en `objects`-hanterare.

### Baschefer

Model._base_manager

#### Använda chefer för åtkomst till relaterade objekt

Som standard använder Django en instans av managerklassen `Model._base_manager` vid åtkomst till relaterade objekt (t.ex. `choice.question`), inte `_default_manager` på det relaterade objektet. Detta beror på att Django måste kunna hämta det relaterade objektet, även om det annars skulle filtreras bort (och därmed vara otillgängligt) av standardhanteraren.

Om den normala bashanterarklassen (`django.db.models.Manager`) inte är lämplig för dina omständigheter kan du berätta för Django vilken klass som ska användas genom att ställa in `Meta.base_manager_name`.

Bashanterare används inte vid frågor om relaterade modeller, eller när åtkomst till en en-till-man eller många-till-man relation. Om till exempel modellen `Question` :ref:` från handledningen <creating-models>` hade ett fält `deleted` och en bashanterare som filtrerar bort instanser med `deleted=True`, skulle en frågeuppsättning som `Choice.objects.filter(question__name__startswith='What')` inkludera val som är relaterade till borttagna frågor.

#### Filtrera inte bort några resultat i den här typen av manager-underklass

Denna manager används för att komma åt objekt som är relaterade till från någon annan modell. I dessa situationer måste Django kunna se alla objekt för den modell som hämtas, så att allt som hänvisas till kan hämtas.

Därför bör du inte åsidosätta `get_queryset()` för att filtrera bort några rader. Om du gör det kommer Django att returnera ofullständiga resultat.

### Anropa anpassade metoder för `QuerySet` från hanteraren

Medan de flesta metoder från standard `QuerySet` är tillgängliga direkt från `Manager`, är detta endast fallet för de extra metoder som definieras på en anpassad `QuerySet` om du också implementerar dem på `Manager`:

    class PersonQuerySet(models.QuerySet):
        def authors(self):
            return self.filter(role="A")

        def editors(self):
            return self.filter(role="E")

    class PersonManager(models.Manager):
        def get_queryset(self):
            return PersonQuerySet(self.model, using=self._db)

        def authors(self):
            return self.get_queryset().authors()

        def editors(self):
            return self.get_queryset().editors()

    class Person(models.Model):
        first_name = models.CharField(max_length=50)
        last_name = models.CharField(max_length=50)
        role = models.CharField(max_length=1, choices={"A": _("Author"), "E": _("Editor")})
        people = PersonManager()

I det här exemplet kan du anropa både `authors()` och `editors()` direkt från hanteraren `Person.people`.

### Skapa en manager med `QuerySet`-metoder

I stället för ovanstående tillvägagångssätt som kräver duplicering av metoder på både `QuerySet` och `Manager`, `QuerySet.as_manager()` kan användas för att skapa en instans av `Manager` med en kopia av en anpassad `QuerySet`’s metoder:

    class Person(models.Model):
        ...
        people = PersonQuerySet.as_manager()

Instansen `Manager` som skapas av `QuerySet.as_manager()` kommer att vara praktiskt taget identisk med `PersonManager` från föregående exempel.

Inte alla `QuerySet` -metoder är meningsfulla på `Manager` -nivån; till exempel förhindrar vi avsiktligt `QuerySet.delete()` -metoden från att kopieras till `Manager` -klassen.

Metoderna kopieras enligt följande regler:

- Publika metoder kopieras som standard.

- Privata metoder (som börjar med en understrykning) kopieras inte som standard.

- Metoder med attributet `queryset_only` inställt på `False` kopieras alltid.

- Metoder med attributet `queryset_only` inställt på `True` kopieras aldrig.

Till exempel:

    class CustomQuerySet(models.QuerySet):
        # Available on both Manager and QuerySet.
        def public_method(self):
            return

        # Available only on QuerySet.
        def _private_method(self):
            return

        # Available only on QuerySet.
        def opted_out_public_method(self):
            return

        opted_out_public_method.queryset_only = True

        # Available on both Manager and QuerySet.
        def _opted_in_private_method(self):
            return

        _opted_in_private_method.queryset_only = False

#### `from_queryset()`

classmethod from_queryset(queryset_class)

För avancerad användning kanske du vill ha både en anpassad `Manager` och en anpassad `QuerySet`. Du kan göra det genom att anropa `Manager.from_queryset()` som returnerar en subklass av din bas `Manager` med en kopia av de anpassade `QuerySet` metoderna:

    class CustomManager(models.Manager):
        def manager_only_method(self):
            return

    class CustomQuerySet(models.QuerySet):
        def manager_and_queryset_method(self):
            return

    class MyModel(models.Model):
        objects = CustomManager.from_queryset(CustomQuerySet)()

Du kan också lagra den genererade klassen i en variabel:

    MyManager = CustomManager.from_queryset(CustomQuerySet)

    class MyModel(models.Model):
        objects = MyManager()

### Anpassade förvaltare och modellarv

Så här hanterar Django egna managers och modellarv:

1. Hanterare från basklasser ärvs alltid av underklassen, med Pythons normala namnupplösningsordning (namn på underklassen åsidosätter alla andra; sedan kommer namn på den första föräldraklassen, och så vidare).

2. Om inga managers deklareras på en modell och/eller dess föräldrar skapar Django automatiskt manager `objects`.

3. Standardhanteraren för en klass är antingen den som valts med `Meta.default_manager_name`, eller den första hanteraren som deklarerats på modellen, eller standardhanteraren för den första överordnade modellen.

Dessa regler ger den flexibilitet som krävs om du vill installera en samling anpassade hanterare på en grupp modeller, via en abstrakt basklass, men ändå anpassa standardhanteraren. Anta till exempel att du har den här basklassen:

    class AbstractBase(models.Model):
        # ...
        objects = CustomManager()

        class Meta:
            abstract = True

Om du använder detta direkt i en underordnad klass kommer `objects` att vara standardhanteraren om du inte deklarerar några hanterare i den underordnade klassen:

    class ChildA(AbstractBase):
        # ...
        # This class has CustomManager as the default manager.
        pass

Om du vill ärva från `AbstractBase`, men tillhandahålla en annan standardhanterare, kan du ange standardhanteraren på barnklassen:

    class ChildB(AbstractBase):
        # ...
        # An explicit default manager.
        default_manager = OtherManager()

Här är `default_manager` standard. Hanteraren `objects` är fortfarande tillgänglig, eftersom den ärvs, men används inte som standard.

Slutligen för det här exemplet, anta att du vill lägga till extra chefer i barnklassen, men fortfarande använda standard från `AbstractBase`. Du kan inte lägga till den nya hanteraren direkt i barnklassen, eftersom det skulle åsidosätta standardvärdet och du måste också uttryckligen inkludera alla hanterare från den abstrakta basklassen. Lösningen är att lägga de extra förvaltarna i en annan basklass och införa den i arvshierarkin efter standardvärdena:

    class ExtraManager(models.Model):
        extra_manager = OtherManager()

        class Meta:
            abstract = True

    class ChildC(AbstractBase, ExtraManager):
        # ...
        # Default manager is CustomManager, but OtherManager is
        # also available via the "extra_manager" attribute.
        pass

Observera att även om du kan definiera en anpassad manager på den abstrakta modellen, kan du inte invoke några metoder som använder den abstrakta modellen. Det vill säga:

    ClassA.objects.do_something()

är lagligt, men:

    AbstractBase.objects.do_something()

kommer att ge upphov till ett undantag. Detta beror på att managers är avsedda att kapsla in logik för att hantera samlingar av objekt. Eftersom du inte kan ha en samling av abstrakta objekt är det inte meningsfullt att hantera dem. Om du har funktionalitet som gäller för den abstrakta modellen bör du lägga den funktionaliteten i en `staticmethod` eller `classmethod` på den abstrakta modellen.

### Problem med genomförandet

Oavsett vilka funktioner du lägger till i din anpassade `Manager` måste det vara möjligt att göra en ytlig kopia av en `Manager`-instans, dvs. följande kod måste fungera:

    >>> import copy
    >>> manager = MyManager()
    >>> my_copy = copy.copy(manager)

Django gör ytliga kopior av managerobjekt under vissa frågor; om din manager inte kan kopieras kommer dessa frågor att misslyckas.

Detta kommer inte att vara ett problem för de flesta anpassade förvaltare. Om du bara lägger till enkla metoder till din `Manager` är det osannolikt att du oavsiktligt kommer att göra instanser av din `Manager` okopierbara. Men om du åsidosätter `__getattr__` eller någon annan privat metod i ditt `Manager`-objekt som kontrollerar objektets tillstånd, bör du se till att du inte påverkar möjligheten för din `Manager` att kopieras.