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_setet pourpizza.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=Falsepour que la mise à jour soit effectuée plutôt par le gestionnaire de la relation en appelante.save().Cependant, l’emploi de
add()avec une relation plusieurs-à-plusieurs n’appelle aucune méthodesave()(le paramètrebulkn’existe pas), mais crée plutôt les relations en utilisantQuerySet.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 signalm2m_changed, qui va déclencher les actionspre_addetpost_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*objssoit des instances de modèles, soit des valeurs de champs, en principe des clés primaires.Utilisez le paramètre
through_defaultspour définir les valeurs des nouvelles instances du modèle intermédiaire, si nécessaire. Vous pouvez utiliser des valeurs exécutables dans le dictionnairethrough_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:
acreateCré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 champblogdu nouvel objetEntrydoit recevoir la valeurb.Utilisez le paramètre
through_defaultspour définir les valeurs des nouvelles instances du modèle intermédiaire, si nécessaire. Vous pouvez utiliser des valeurs exécutables dans le dictionnairethrough_defaults.
- remove(*objs, bulk=True)¶
- aremove(*objs, bulk=True)¶
Version asynchrone:
aremoveEnlè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 appellee.save()dans l’exemple ci-dessus pour effectuer la mise à jour. Cependant, l’emploi deremove()avec une relation plusieurs-à-plusieurs supprime les relations avecQuerySet.delete(), ce qui signifie qu’aucune méthodesave()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 signalm2m_changed.Pour les relations plusieurs-à-plusieurs,
remove()accepte dans le paramètre*objssoit 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 quandnull=True. Si le champ lié ne peut pas recevoir la valeurNone(NULL), alors un objet ne peut pas être enlevé d’une relation sans être ajouté à une autre. Dans l’exemple ci-dessus, enleveredeb.entry_set()est l’équivalent de la définitione.blog = None, et comme la cléForeignKeyblogn’a pas l’optionnull=True, ce n’est pas valide.Pour les objets
ForeignKey, cette méthode accepte un paramètrebulkpour contrôler comment effectuer l’opération. AvecTrue(valeur par défaut), c’estQuerySet.update()qui est utilisé. Avecbulk=False, c’est plutôt la méthodesave()de chaque instance de modèle individuelle qui est appelée. Cela déclenche les signauxpre_saveetpost_saveau détriment d’une perte de performance.Pour les relations plusieurs-à-plusieurs, le paramètre nommé
bulkn’existe pas.
- clear(bulk=True)¶
- aclear(bulk=True)¶
Version asynchrone:
aclearEnlè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 champForeignKeyque lorsquenull=Trueet il accepte également le paramètre nommébulk.Pour les relations plusieurs-à-plusieurs, le paramètre nommé
bulkn’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
clearpour contrôler le fonctionnement de l’opération. SiFalse(par défaut), les éléments manquants dans le nouvel ensemble sont supprimés avecremove()et seuls les nouveaux sont ajoutés. Siclear=True, la méthodeclear()est appelée à la place et l’ensemble est ajouté en une seule fois.Pour les objets
ForeignKey, le paramètrebulkest transmis àadd()et àremove().Pour les relations plusieurs-à-plusieurs, le paramètre nommé
bulkn’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’appelclear()et l’appeladd().Pour les relations plusieurs-à-plusieurs,
set()accepte dans le paramètreobjssoit 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_defaultspour définir les valeurs des nouvelles instances du modèle intermédiaire, si nécessaire. Vous pouvez utiliser des valeurs exécutables dans le dictionnairethrough_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()etaset()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’appelersave()/asave()ni d’un côté de la relation, ni de l’autre.Si vous utilisez
prefetch_related(), les méthodesadd(),aadd(),remove(),aremove(),clear(),aclear(),set()etaset()effacent le cache de préchargement.