Django crée automatiquement des outils pour naviguer dans les relations entre vos modèles, y compris les **relations inverses**. Ces outils sont appelés **gestionnaires de relations (RelatedManager)**. Pour les champs ManyToManyField, comprendre et maîtriser le gestionnaire par défaut (_set) et sa personnalisation (related_name) est fondamental.
ManyToManyField
_set
related_name
Rappel : Un ManyToManyField ne doit être défini que sur l'un des deux modèles pour établir une relation bidirectionnelle (comme l'indique cet excellent lien sur StackOverflow : Différence entre les champs de relation).
Considérons les deux modèles suivants qui définissent une relation Plusieurs-à-Plusieurs (Many-to-Many) où un utilisateur peut appartenir à plusieurs entreprises et vice-versa :
class User(models.Model): username = models.CharField(max_length=100, unique=True) companies = models.ManyToManyField('Company', blank=True) class Company(models.Model): name = models.CharField(max_length=255)
Pour obtenir toutes les entreprises d'un utilisateur, on utilise le nom du champ :
user_instance.companies.all()
Puisque le modèle Company n'a pas de champ explicite pointant vers User, Django crée automatiquement un gestionnaire d'accès inverse. Ce gestionnaire est nommé en utilisant la syntaxe : <modèle_source_en_minuscule>_set.
Company
User
<modèle_source_en_minuscule>_set
Dans notre cas, le modèle source de la relation inverse est **`User`**. Le gestionnaire s'appelle donc user_set :
user_set
# Accès inverse par défaut : Obtenir tous les utilisateurs d'une entreprise company_instance.user_set.all() # Retourne un QuerySet d’objets User.
Ce mécanisme est la manière dont Django gère par défaut l'accès depuis l'objet qui ne porte pas la définition du champ relationnel.
Le nom par défaut _set est souvent peu clair. Il est fortement recommandé d'utiliser l'argument **related_name** lors de la définition du champ ManyToManyField pour spécifier un nom de gestionnaire inverse plus explicite.
Nous remplaçons user_set par le nom plus logique users :
users
class User(models.Model): username = models.CharField(max_length=100, unique=True) # Définition du nom de la relation inverse comme 'users' companies = models.ManyToManyField('Company', blank=True, related_name='users') class Company(models.Model): name = models.CharField(max_length=255)
L'accès inverse devient alors plus intuitif :
# Accès inverse personnalisé : Obtenir tous les utilisateurs d'une entreprise company_instance.users.all()
L'utilisation de related_name rend votre code plus lisible et évite les conflits potentiels si plusieurs relations pointent vers le même modèle.
Découvrez nos actualités, conseils et tutoriels pour rester à jour
FastAPI est un framework Python moderne qui per...
Ce guide est conçu pour les début...
Distribuer une application Django à des...
Dans le monde Python, Celery est un outil popul...
Inscription en cours...
Restez informé de nos dernières actualités et recevez nos meilleurs conseils !
Chargement du formulaire de devis...