---
title: "Gestionnaires"
version: 1.9
locale: fr
source: https://docs.djangoproject.com/fr/1.9/topics/db/managers/
canonical: https://djangodocs.dev/fr/1.9/topics/db/managers/
---
# Gestionnaires

#### `class Manager`

Un gestionnaire (objet `Manager`) est l’interface par laquelle les opérations de requêtes de base de données sont mises à disposition des modèles Django. Il existe au moins un `Manager` pour chaque modèle d’une application Django.

Le fonctionnement des classes `Manager` est documenté dans [Création de requêtes](/fr/1.9/topics/db/queries/); ce document aborde spécifiquement les options de modèles qui personnalisent le comportement des gestionnaires.

## Noms des gestionnaires

Par défaut, Django ajoute un gestionnaire nommé `objects` à chaque classe de modèle Django. Cependant, si vous aimeriez utiliser `objects` comme nom de champ ou que vous aimeriez nommer le gestionnaire autrement que `objects`, vous pouvez le renommer au niveau du modèle. Pour renommer le gestionnaire d’une classe donnée, définissez un attribut de classe de type `models.Manager()` dans le modèle. Par exemple :

```
from django.db import models

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

En utilisant cet exemple de modèle, `Person.objects` générera une exception `AttributeError`, mais `Person.people.all()` fournira effectivement la liste de tous les objets `Person`.

## Gestionnaires personnalisés

Vous pouvez utiliser un gestionnaire personnalisé dans un modèle particulier en étendant la classe `Manager` de base et en créant votre propre instance de `Manager` dans votre modèle.

Il y a deux raisons de vouloir personnaliser un gestionnaire : pour lui ajouter des méthodes supplémentaires ou pour modifier l’objet `QuerySet` initial que le gestionnaire renvoie.

### Ajout de méthodes de gestionnaire supplémentaires

L’ajout de méthodes de gestionnaire supplémentaires est la façon privilégiée d’ajouter des fonctionnalités au « niveau table » à des modèles (pour les fonctionnalités au « niveau ligne », c’est-à-dire les fonctions qui agissent sur une seule instance d’un objet de modèle, utilisez les [méthodes de modèles](/fr/1.9/topics/db/models/#model-methods) et non pas des méthodes de gestionnaire personnalisées).

Une méthode de gestionnaire personnalisée peut renvoyer tout ce qu’on veut, elle n’est pas tenue de renvoyer un objet `QuerySet`.

Par exemple, cette méthode de gestionnaire personnalisée offre une méthode `with_counts()` qui renvoie une liste de tous les objets `OpinionPoll`, chacun recevant un attribut supplémentaire `num_responses` qui est le résultat d’une requête d’agrégation :

```
from django.db import models

class PollManager(models.Manager):
    def with_counts(self):
        from django.db import connection
        cursor = connection.cursor()
        cursor.execute("""
            SELECT p.id, p.question, p.poll_date, COUNT(*)
            FROM polls_opinionpoll p, polls_response r
            WHERE p.id = r.poll_id
            GROUP BY p.id, p.question, p.poll_date
            ORDER BY p.poll_date DESC""")
        result_list = []
        for row in cursor.fetchall():
            p = self.model(id=row[0], question=row[1], poll_date=row[2])
            p.num_responses = row[3]
            result_list.append(p)
        return result_list

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

class Response(models.Model):
    poll = models.ForeignKey(OpinionPoll, on_delete=models.CASCADE)
    person_name = models.CharField(max_length=50)
    response = models.TextField()
```

Avec cet exemple, vous écririez `OpinionPoll.objects.with_counts()` pour obtenir la liste des objets `OpinionPoll` comportant l’attribut `num_responses`.

Une autre chose à relever au sujet de cet exemple est que les méthodes de gestionnaire ont accès à `self.model` pour obtenir la classe de modèle à laquelle elles sont liées.

### Modification des `QuerySet` initiaux des gestionnaires

Le `QuerySet` de base d’un gestionnaire renvoie tous les objets du système. Par exemple, en utilisant ce modèle :

```
from django.db import models

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

…l’instruction `Book.objects.all()` renvoie tous les livres de la base de données.

Vous pouvez surcharger le `QuerySet` de base d’un gestionnaire en surchargeant la méthode `Manager.get_queryset()`. `get_queryset()` doit renvoyer un objet `QuerySet` doté des propriétés nécessaires.

Par exemple, le modèle suivant possède *deux* gestionnaires, un qui renvoie tous les objets et un autre qui ne renvoie que les livres de Roald Dahl :

```
# First, define the Manager subclass.
class DahlBookManager(models.Manager):
    def get_queryset(self):
        return super(DahlBookManager, self).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.
```

Avec cet exemple de modèle, `Book.objects.all()` renvoie tous les livres de la base de données, mais `Book.dahl_objects.all()` ne retourne que ceux qui ont été écrits par Roald Dahl.

Naturellement, comme `get_queryset()` renvoie un objet `QuerySet`, vous pouvez appliquer `filter()`, `exclude()` et toutes les autres méthodes de `QuerySet`. Ainsi, ces instructions sont toutes valables :

```
Book.dahl_objects.all()
Book.dahl_objects.filter(title='Matilda')
Book.dahl_objects.count()
```

Cet exemple a aussi mis en évidence une autre technique intéressante : l’emploi de plusieurs gestionnaires dans un même modèle. Vous pouvez lier autant d’instances de gestionnaires que vous voulez à un modèle. C’est une manière simple de définir des « filtres » fréquemment utilisés dans des modèles.

Par exemple :

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

class EditorManager(models.Manager):
    def get_queryset(self):
        return super(EditorManager, self).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()
```

Cet exemple permet d’effectuer les requêtes `Person.authors.all()`, `Person.editors.all()` et `Person.people.all()` en sachant à quoi vous attendre au niveau des résultats.

#### Gestionnaires par défaut

Si vous utilisez des objets `Manager` personnalisés, sachez que le premier `Manager` que Django rencontre (dans l’ordre où ils ont été définis dans le modèle) reçoit un statut spécial. Django interprète le premier gestionnaire défini dans une classe comme le gestionnaire par défaut, et plusieurs parties de Django (y compris [`dumpdata`](/fr/1.9/ref/django-admin/#django-admin-dumpdata)) utilisent exclusivement ce gestionnaire pour le modèle en question. En conséquence, il est conseillé de choisir avec prudence le gestionnaire par défaut afin d’éviter une situation où la surcharge de `get_queryset()` aboutit à l’incapacité de récupérer des objets avec lesquels vous avez besoin de travailler.

#### Utilisation de gestionnaires pour accéder aux objets liés

Par défaut, Django utilise une instance de classe de gestionnaire « normale » pour accéder aux objets liés (par ex. `choice.poll`), et non pas le gestionnaire par défaut de l’objet lié. Ceci parce que Django doit absolument être capable de récupérer l’objet lié, même dans les cas où il serait filtré (et donc inaccessible) par son gestionnaire par défaut.

Si la classe de gestionnaire normale ([`django.db.models.Manager`](#django.db.models.Manager)) ne convient pas dans un cas particulier, vous pouvez forcer Django à utiliser la même classe que le gestionnaire par défaut du modèle et définissant l’attribut `use_for_related_fields` dans la classe du gestionnaire. Vous en trouverez la documentation complète [ci-dessous](#manager-types).

### Appel personnalisé de méthodes `QuerySet` depuis le gestionnaire

Alors que la plupart des méthodes d’un `QuerySet` standard sont directement accessibles à partir d’un `Manager`, ce n’est le cas pour les méthodes supplémentaires définies sur un `QuerySet` personnalisé que si vous les implémentez également sur le `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()
```

Cet exemple permet d’appeler `authors()` et `editors()` directement depuis le gestionnaire `Person.people`.

### Création d’objet `Manager` avec des méthodes de `QuerySet`

En lieu et place de l’approche ci-dessus qui nécessite de dupliquer les méthodes à la fois sur les objets `QuerySet` et `Manager`,  [`QuerySet.as_manager()`](/fr/1.9/ref/models/querysets/#django.db.models.query.QuerySet.as_manager) peut être utilisé pour créer une instance de `Manager` avec une copie des méthodes d’un objet `QuerySet` personnalisé :

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

L’instance de `Manager` créée par [`QuerySet.as_manager()`](/fr/1.9/ref/models/querysets/#django.db.models.query.QuerySet.as_manager) sera pratiquement identique au `PersonManager` de l’exemple précédent.

Toutes les méthodes `QuerySet` n’ont pas forcément de sens au niveau `Manager`; par exemple, nous empêchons volontairement la méthode [`QuerySet.delete()`](/fr/1.9/ref/models/querysets/#django.db.models.query.QuerySet.delete) d’être copiée vers la classe `Manager`.

Les méthodes sont copiées selon les règles suivantes :

- Les méthodes publiques sont copiées par défaut.
- Les méthodes privées (commençant par un soulignement) ne sont pas copiées par défaut.
- Les méthodes avec un attribut `queryset_only` à `False` sont toujours copiées.
- Les méthodes avec un attribut `queryset_only` à `True` ne sont jamais copiées.

Par exemple :

```
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)`

Pour une utilisation plus avancée, il peut être souhaitable d’avoir à la fois un `Manager` personnalisé et un `QuerySet` personnalisé. Vous pouvez le faire en appelant `Manager.from_queryset()` qui renvoie une *sous-classe* du `Manager` de base avec une copie des méthodes `QuerySet` personnalisées :

```
class BaseManager(models.Manager):
    def manager_only_method(self):
        return

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

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

Vous pouvez également stocker la classe générée dans une variable :

```
CustomManager = BaseManager.from_queryset(CustomQuerySet)

class MyModel(models.Model):
    objects = CustomManager()
```

### Gestionnaires personnalisés et héritage de modèle

L’héritage de classes et les gestionnaires de modèle ne font pas très bon ménage. Les gestionnaires sont souvent spécifiques aux classes dans lesquelles ils sont définis et leur héritage dans des sous-classes n’est pas forcément toujours une bonne idée. Et comme le premier gestionnaire défini devient le *gestionnaire par défaut*, il est important de pouvoir contrôler cet ordre de définition. Voici donc comment Django se comporte face aux gestionnaires personnalisés et à [l’héritage de modèles](/fr/1.9/topics/db/models/#model-inheritance):

1. Les gestionnaires définis dans les classes de base non abstraites ne sont *pas* hérités par les classes enfants. Si vous souhaitez réutiliser un gestionnaire d’une base non abstraite, il faut le redéclarer explicitement dans la classe enfant. Ce type de gestionnaire est généralement très spécifique à la classe dans laquelle il est défini, c’est pourquoi leur héritage pourrait produire des résultats inattendus (particulièrement lorsqu’il s’agit du gestionnaire par défaut). Ils ne sont donc pas transmis à leurs classes enfants.
2. Les gestionnaires des classes de base abstraites sont toujours hérités par les classes enfants, par le moyen Python habituel de l’ordre de résolution de nom (les noms des classes enfants surchargent ceux de leurs parents). Les classes de base abstraites sont conçues pour centraliser les informations et les comportements communs à leurs classes enfants. La définition de gestionnaires communs est un aspect entrant tout à fait dans ces informations communes.
3. Le gestionnaire par défaut d’une classe est soit le premier gestionnaire déclaré dans la classe, s’il y en a un, ou le gestionnaire par défaut de la première classe de base abstraite dans la hiérarchie d’héritage, le cas échéant. Si aucun gestionnaire par défaut n’est explicitement déclaré, c’est le gestionnaire par défaut habituel de Django qui est utilisé.

Ces règles assurent la souplesse nécessaire permettant d’installer un ensemble de gestionnaires personnalisés sur un groupe de modèles via une classe de base abstraite, tout en personnalisant aussi le gestionnaire par défaut. Prenons l’exemple de cette classe de base :

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

    class Meta:
        abstract = True
```

Si vous l’utilisez directement dans une sous-classe, `objects` sera le gestionnaire par défaut si aucun gestionnaire n’est déclaré dans la classe de base :

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

Si vous voulez hériter de `AbstractBase`, mais avec un autre gestionnaire par défaut, vous pouvez définir le gestionnaire par défaut dans la classe enfant :

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

Ici, `default_manager` est le gestionnaire par défaut. Le gestionnaire `objects` est toujours disponible, puisqu’il est hérité. Il n’est juste plus le gestionnaire par défaut.

Pour terminer avec cet exemple, supposons que vous vouliez ajouter des gestionnaires supplémentaires dans la classe enfant tout en conservant le gestionnaire par défaut de `AbstractBase`. Vous ne pouvez pas ajouter directement le nouveau gestionnaire dans la classe enfant, car cela surchargerait le gestionnaire par défaut et vous devriez aussi inclure explicitement tous les gestionnaires de la classe de base abstraite. La solution est de placer les gestionnaires supplémentaires dans une autre classe de base et introduire celle-ci dans la hiérarchie d’héritage *après* ceux par défaut :

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

Notez que même si vous pouvez *définir* un gestionnaire personnalisé dans le modèle abstrait, vous ne pouvez *appeler* aucune de ses méthodes au travers du modèle abstrait. C’est-à-dire :

```
ClassA.objects.do_something()
```

est légal, mais :

```
AbstractBase.objects.do_something()
```

générera une exception. C’est parce que les gestionnaires sont censés intégrer la logique de gestion d’ensembles d’objets. Comme il n’est pas possible d’avoir un ensemble d’objets abstraits, leur gestion n’a pas de sens. Si vous gérez des fonctionnalités s’appliquant au modèle abstrait, vous devriez les placer dans une méthode `staticmethod` ou `classmethod` du modèle abstrait.

### Détails d’implémentation

Quelles que soient les fonctionnalités ajoutées à un gestionnaire personnalisé, il doit toujours être possible de faire une copie légère (« shallow ») d’une de ses instances ; c’est-à-dire que le code suivant doit fonctionner :

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

Django effectue des copies légères des objets de gestionnaire durant certaines requêtes ; si votre gestionnaire ne peut pas être copié, ces requêtes échoueront.

Ce ne sera pas un problème pour la plupart des gestionnaires personnalisés. Si vous ne faites qu’ajouter des méthodes simples à votre classe `Manager`, il est improbable que vous empêchiez la copie de votre gestionnaire sans le vouloir. Cependant, si vous surchargez `__getattr__` ou d’autres méthodes privées de l’objet `Manager` qui contrôlent l’état de l’objet, il faut vous assurer que vous n’altériez pas la capacité de votre gestionnaire d’être copié.

## Contrôle du type des gestionnaires automatiques

Ce document a déjà mentionné quelques endroits où Django crée automatiquement une classe de gestionnaire : [gestionnaires par défaut](#id3) et le gestionnaire « de base » utilisé pour [accéder aux objets liés](#manager-names). Il y a d’autres endroits dans l’implémentation de Django où des gestionnaires de base temporaires sont nécessaires. Ces gestionnaires automatiquement créés sont normalement des instances de la classe [`django.db.models.Manager`](#django.db.models.Manager).

Tout au long de cette section, nous utiliserons le terme « gestionnaire automatique » pour désigner les gestionnaires que Django crée pour vous, soit comme un gestionnaire par défaut d’un modèle sans gestionnaire ou pour un usage temporaire lors de l’accès à des objets liés.

Cette classe par défaut n’est parfois pas le bon choix. Le gestionnaire par défaut peut ne pas disposer de toutes les méthodes nécessaires à la manipulation des données. Une classe de gestionnaire personnalisée selon vos besoins permet de créer des objets `QuerySet` personnalisés pour obtenir les informations dont vous avez besoin.

Django propose aux développeurs de gestionnaires personnalisés une manière d’indiquer que leur classe de gestionnaire doit être utilisée pour les gestionnaires automatiques chaque fois qu’ils deviennent le gestionnaire par défaut d’un modèle. Ceci se fait en définissant l’attribut `use_for_related_fields` dans la classe du gestionnaire :

```
class MyManager(models.Manager):
    use_for_related_fields = True
    # ...
```

Si cet attribut est défini dans le gestionnaire *par défaut* d’un modèle (seul le gestionnaire par défaut est considéré dans ces situations), Django utilise cette classe chaque fois qu’il a besoin de créer automatiquement un gestionnaire pour la classe. Sinon, il utilise [`django.db.models.Manager`](#django.db.models.Manager).

> **Note historique**
>
> Étant donné le but pour lequel il est utilisé, le nom de cet attribut (`use_for_related_fields`) peut sembler un peu bizarre. À l’origine, cet attribut ne contrôlait que le type de gestionnaire utilisé pour l’accès aux champs liés, d’où son nom. Ce nom n’a ensuite pas été modifié, même quand il paraissait de plus en plus clair que le concept était plus largement utile. Ceci principalement pour [préserver le fonctionnement du code existant](/fr/1.9/misc/api-stability/) dans les versions futures de Django.

### Écriture correcte de gestionnaires pour les instances automatiques

La fonctionnalité `use_for_related_fields` est principalement axée sur les gestionnaires qui ont besoin de renvoyer une sous-classe de `QuerySet` personnalisée. Lorsque vous utilisez cette fonctionnalité dans un gestionnaire, il ne fait pas oublier certaines choses.

#### Ne jamais filtrer les résultats dans ce type de sous-classe de gestionnaire

L’une des raisons pour lesquelles un gestionnaire automatique est utilisé est le besoin d’accéder aux objets liés à partir d’un autre modèle. Dans ces situations, Django doit être capable de voir tous les objets du modèle qu’il récupère, afin que *tout* ce qui est référencé puisse être récupéré.

Si vous surchargez la méthode `get_queryset()` et que vous excluez certaines lignes, Django renverra des résultats incorrects. Ne faites pas cela. Un gestionnaire excluant des résultats dans `get_queryset()` n’est pas approprié comme gestionnaire automatique.

#### Définir `use_for_related_fields` lors de la création de la classe

L’attribut `use_for_related_fields` doit être défini dans la *classe* du gestionnaire, et non pas dans une *instance* de la classe. L’exemple précédent montre la bonne manière de le faire, tandis que le code suivant ne fonctionnera pas :

```
# BAD: Incorrect code
class MyManager(models.Manager):
    # ...
    pass

# Sets the attribute on an instance of MyManager. Django will
# ignore this setting.
mgr = MyManager()
mgr.use_for_related_fields = True

class MyModel(models.Model):
    # ...
    objects = mgr

# End of incorrect code.
```

De plus, vous ne devriez pas modifier l’attribut de l’objet classe après qu’il a été utilisé dans un modèle, car la valeur de l’attribut est prise en compte au moment de la création de la classe de modèle et n’est plus relue plus tard. Définissez l’attribut de la classe de gestionnaire lors de sa définition initiale comme dans le premier exemple de cette section et tout devrait fonctionner à merveille.
