# Documentation Django 6.0.7

# Référence des objets liés

class RelatedManager

  Un gestionnaire de liaison (« related manager ») est un gestionnaire utilisé dans un contexte de champ lié un-à-plusieurs ou plusieurs-à-plusieurs. Cela se produit dans deux cas :

  - Le « côté opposé » d’une relation `ForeignKey`. C’est-à-dire :

        from django.db import models

        class Blog(models.Model):
            # ...
            pass

        class Entry(models.Model):
            blog = models.ForeignKey(Blog, on_delete=models.CASCADE, null=True)

    Dans l’exemple ci-dessus, les méthodes ci-dessous seront disponibles pour le gestionnaire `blog.entry_set`.

  - Les deux côtés d’une relation `ManyToManyField`:

        class Topping(models.Model):
            # ...
            pass

        class Pizza(models.Model):
            toppings = models.ManyToManyField(Topping)

    Dans cet exemple, les méthodes ci-dessous seront disponibles à la fois pour `topping.pizza_set` et pour `pizza.toppings`.

  add(*objs, bulk=True, through_defaults=None)
  aadd(*objs, bulk=True, through_defaults=None)

    Version asynchrone: `aadd()`

    Ajoute les objets modèles indiqués à l’ensemble des objets liés.

    Exemple :

        >>> b = Blog.objects.get(id=1)
        >>> e = Entry.objects.get(id=234)
        >>> b.entry_set.add(e)  # Associates Entry e with Blog b.

    Dans l’exemple ci-dessus, dans le cas d’une relation `ForeignKey`, `QuerySet.update()` est utilisée pour effectuer la mise à jour. Ceci nécessite que les objets soient déjà enregistrés.

    Vous pouvez utiliser le paramètre `bulk=False` pour que la mise à jour soit effectuée plutôt par le gestionnaire de la relation en appelant `e.save()`.

    Cependant, l’emploi de `add()` avec une relation plusieurs-à-plusieurs n’appelle aucune méthode `save()` (le paramètre `bulk` n’existe pas), mais crée plutôt les relations en utilisant `QuerySet.bulk_create()`. Si vous avez besoin de faire exécuter une certaine logique personnalisée lors de la création d’une relation, faites-le dans une fonction à l’écoute du signal `m2m_changed`, qui va déclencher les actions `pre_add` et `post_add`.

    L’utilisation de `add()` sur une relation qui existe déjà ne va pas dupliquer la relation, mais cela va tout de même déclencher les signaux.

    Pour les relations plusieurs-à-plusieurs, `add()` accepte dans le paramètre `*objs` soit des instances de modèles, soit des valeurs de champs, en principe des clés primaires.

    Utilisez le paramètre `through_defaults` pour définir les valeurs des nouvelles instances du modèle intermédiaire, si nécessaire. Vous pouvez utiliser des valeurs exécutables dans le dictionnaire `through_defaults`, elles seront évaluées une fois avant la création d’instances intermédiaires.

  create(through_defaults=None, **kwargs)
  acreate(through_defaults=None, **kwargs)

    Version asynchrone: `acreate`

    Crée un nouvel objet, l’enregistre et le place dans l’ensemble des objets liés. Renvoie l’objet nouvellement créé :

        >>> b = Blog.objects.get(id=1)
        >>> e = b.entry_set.create(
        ...     headline="Hello", body_text="Hi", pub_date=datetime.date(2005, 1, 1)
        ... )

        # No need to call e.save() at this point -- it's already been saved.

    C’est équivalent à (mais plus simple) :

        >>> b = Blog.objects.get(id=1)
        >>> e = Entry(blog=b, headline="Hello", body_text="Hi", pub_date=datetime.date(2005, 1, 1))
        >>> e.save(force_insert=True)

    Notez qu’il n’y a pas besoin de fournir le paramètre nommé du modèle qui définit la relation. Dans l’exemple ci-dessus, nous ne transmettons pas le paramètre `blog` à `create()`. Django réalise lui-même que le champ `blog` du nouvel objet `Entry` doit recevoir la valeur `b`.

    Utilisez le paramètre `through_defaults` pour définir les valeurs des nouvelles instances du modèle intermédiaire, si nécessaire. Vous pouvez utiliser des valeurs exécutables dans le dictionnaire `through_defaults`.

  remove(*objs, bulk=True)
  aremove(*objs, bulk=True)

    Version asynchrone: `aremove`

    Enlève les objets modèles indiqués de l’ensemble des objets liés :

        >>> b = Blog.objects.get(id=1)
        >>> e = Entry.objects.get(id=234)
        >>> b.entry_set.remove(e)  # Disassociates Entry e from Blog b.

    Comme avec `add()`, on appelle `e.save()` dans l’exemple ci-dessus pour effectuer la mise à jour. Cependant, l’emploi de `remove()` avec une relation plusieurs-à-plusieurs supprime les relations avec `QuerySet.delete()`, ce qui signifie qu’aucune méthode `save()` n’est appelée. Si vous avez besoin de faire exécuter du code personnalisé lors de la suppression d’une relation, faites-le dans une fonction à l’écoute du signal `m2m_changed`.

    Pour les relations plusieurs-à-plusieurs, `remove()` accepte dans le paramètre `*objs` soit des instances de modèles, soit des valeurs de champs, en principe des clés primaires.

    Pour les objets `ForeignKey`, cette méthode existe seulement quand `null=True`. Si le champ lié ne peut pas recevoir la valeur `None` (`NULL`), alors un objet ne peut pas être enlevé d’une relation sans être ajouté à une autre. Dans l’exemple ci-dessus, enlever `e` de `b.entry_set()` est l’équivalent de la définition `e.blog = None`, et comme la clé `ForeignKey` `blog` n’a pas l’option `null=True`, ce n’est pas valide.

    Pour les objets `ForeignKey`, cette méthode accepte un paramètre `bulk` pour contrôler comment effectuer l’opération. Avec `True` (valeur par défaut), c’est `QuerySet.update()` qui est utilisé. Avec `bulk=False`, c’est plutôt la méthode `save()` de chaque instance de modèle individuelle qui est appelée. Cela déclenche les signaux `pre_save` et `post_save` au détriment d’une perte de performance.

    Pour les relations plusieurs-à-plusieurs, le paramètre nommé `bulk` n’existe pas.

  clear(bulk=True)
  aclear(bulk=True)

    Version asynchrone: `aclear`

    Enlève tous les objets de l’ensemble des objets liés :

        >>> b = Blog.objects.get(id=1)
        >>> b.entry_set.clear()

    Notez que cela ne supprime pas les objets liés, il ne fait que les dissocier.

    Tout comme `remove()`, `clear()` n’est disponible pour un champ `ForeignKey` que lorsque `null=True` et il accepte également le paramètre nommé `bulk`.

    Pour les relations plusieurs-à-plusieurs, le paramètre nommé `bulk` n’existe pas.

  set(objs, bulk=True, clear=False, through_defaults=None)
  aset(objs, bulk=True, clear=False, through_defaults=None)

    Version asynchrone: `aset()`

    Remplace l’ensemble des objets liés :

        >>> new_list = [obj1, obj2, obj3]
        >>> e.related_set.set(new_list)

    Cette méthode accepte un paramètre `clear` pour contrôler le fonctionnement de l’opération. Si `False` (par défaut), les éléments manquants dans le nouvel ensemble sont supprimés avec `remove()` et seuls les nouveaux sont ajoutés. Si `clear=True`, la méthode `clear()` est appelée à la place et l’ensemble est ajouté en une seule fois.

    Pour les objets `ForeignKey`, le paramètre `bulk` est transmis à `add()` et à `remove()`.

    Pour les relations plusieurs-à-plusieurs, le paramètre nommé `bulk` n’existe pas.

    Notez que dans la mesure où `set()` est une opération composée, elle est sujette aux situations de concurrence. Par exemple, de nouveaux objets pourraient être ajoutés à la base de données entre l’appel `clear()` et l’appel `add()`.

    Pour les relations plusieurs-à-plusieurs, `set()` accepte dans le paramètre `objs` soit une liste d’instances de modèles, soit une liste de valeurs de champs, en principe des clés primaires.

    Utilisez le paramètre `through_defaults` pour définir les valeurs des nouvelles instances du modèle intermédiaire, si nécessaire. Vous pouvez utiliser des valeurs exécutables dans le dictionnaire `through_defaults`, elles seront évaluées une fois avant la création d’instances intermédiaires.

  Note

  Notez que `add()`, `aadd()`, `create()`, `acreate()`, `remove()`, `aremove()`, `clear()`, `aclear()`, `set()` et `aset()` appliquent tous immédiatement les modifications de base de données pour tous les types de champs de relation. En d’autres termes, il n’est pas nécessaire d’appeler `save()`/`asave()` ni d’un côté de la relation, ni de l’autre.

  Si vous utilisez `prefetch_related()`, les méthodes `add()`, `aadd()`, `remove()`, `aremove()`, `clear()`, `aclear()`, `set()` et `aset()` effacent le cache de préchargement.