Django -Gérer les relations Many to Many dans Django
14 déc. 2020
Le framework django implémente dans son ORM un système de relation Many to Many (M2M) afin de mettre en relation un objet avec un autre de façon multiple.
Un objet A peut avoir plusieurs liens avec un objet B, et vis versa.
Sous un digramme UML on le matérialise de cette manière

Et django le comprendra en créant une table d'association (Table AB) pour faire la liaison

Lors de l'écriture de ce modèle, nous devons ajouter un champ ManyToManyField, nous allons voir comment le configurer.
Nous allons créer un objet Article
avec un système de tag pour classifier l'article
Pour mettre en place la relation nous allons utiliser ManyToManyField
Dans quel modèle dois je mettre la relation M2M ?
Tout dépend de votre logique applicative, dans notre exemple il parait plus judicieux de placer cette relation dans le modèle article.
En effet le tag est un élément décrivant votre article, d'ailleurs il peut être absent.
Ces 2 modèles ont été modifiés avec succès il reste maintenant à appliquer les modifications en base de données. Pour cela il suffit de lancer
Django va créer un dossier migrations dans votre projet et ajouter des fichiers contenant les évolutions de votre modèle.
Il est ainsi possible de faire un reverse comme on le voit ligne 12, c'est-à-dire récupérer les objets depuis le modèle qui ne possède pas le champ M2M.
Dans notre exemple le tag n'a pas la relation mais on peut tout de même partir de cet objet pour ensuite obtenir les informations
Un point de vigilance sur cette partie, en effet sauvegarder un modèle via le formulaire de l'admin ne va pas exécuter une transaction de manière atomique.
Une transaction atomique est un ensemble d'opérations pouvant être exécuté entièrement sans pouvoir être interrompu. Une transaction atomique exécutera l'ensemble de nos requêtes ou aucune.
Dans le CRUD de django tant que le formulaire n'est pas terminé la transaction est en cours. Or dans une transaction avec un modèle ayant un M2M il est nécessaire de valider la transaction une première fois afin d'obtenir l'id de l'objet pour l'affecter dans la table d'association.
Ainsi pour pallier à cette problématique il faut valider la transaction avant de pourvoir lié l'objet Tag à l'objet Article
blog comments powered by Disqus
Un objet A peut avoir plusieurs liens avec un objet B, et vis versa.
Sous un digramme UML on le matérialise de cette manière

Et django le comprendra en créant une table d'association (Table AB) pour faire la liaison

Lors de l'écriture de ce modèle, nous devons ajouter un champ ManyToManyField, nous allons voir comment le configurer.
Création des modèles
Nous allons créer un objet Article
avec un système de tag pour classifier l'article
Pour mettre en place la relation nous allons utiliser ManyToManyField
Créer un lien Many to Many
Dans quel modèle dois je mettre la relation M2M ?
Tout dépend de votre logique applicative, dans notre exemple il parait plus judicieux de placer cette relation dans le modèle article.
En effet le tag est un élément décrivant votre article, d'ailleurs il peut être absent.
Appliquer les changements
Ces 2 modèles ont été modifiés avec succès il reste maintenant à appliquer les modifications en base de données. Pour cela il suffit de lancer
python manage.py makemigrations
python manage.py migrate
Django va créer un dossier migrations dans votre projet et ajouter des fichiers contenant les évolutions de votre modèle.
Créer vos objets
Il est ainsi possible de faire un reverse comme on le voit ligne 12, c'est-à-dire récupérer les objets depuis le modèle qui ne possède pas le champ M2M.
Dans notre exemple le tag n'a pas la relation mais on peut tout de même partir de cet objet pour ensuite obtenir les informations
Tag.objects.filter(article=a1)
Et dans l'interface d'administration
Un point de vigilance sur cette partie, en effet sauvegarder un modèle via le formulaire de l'admin ne va pas exécuter une transaction de manière atomique.
Une transaction atomique est un ensemble d'opérations pouvant être exécuté entièrement sans pouvoir être interrompu. Une transaction atomique exécutera l'ensemble de nos requêtes ou aucune.
Dans le CRUD de django tant que le formulaire n'est pas terminé la transaction est en cours. Or dans une transaction avec un modèle ayant un M2M il est nécessaire de valider la transaction une première fois afin d'obtenir l'id de l'objet pour l'affecter dans la table d'association.
Ainsi pour pallier à cette problématique il faut valider la transaction avant de pourvoir lié l'objet Tag à l'objet Article