web-dev-qa-db-fra.com

À quoi sert `related_name` dans Django?

A quoi sert l'argument related_name utile dans les champs ManyToManyField et ForeignKey? Par exemple, étant donné le code suivant, quel est l'effet de related_name='maps'?

class Map(db.Model):
    members = models.ManyToManyField(User, related_name='maps',
                                     verbose_name=_('members'))
316
zjm1126

L'attribut related_name spécifie le nom de la relation inverse du modèle User dans votre modèle.

Si vous ne spécifiez pas de related_name, Django en crée automatiquement un en utilisant le nom de votre modèle avec le suffixe _set, par exemple User.map_set.all().

Si vous spécifiez , par exemple related_name=maps sur le modèle User, User.map_set fonctionnera toujours, mais la syntaxe User.maps. est évidemment un peu plus propre et moins lourde; Ainsi, par exemple, si vous avez un objet utilisateur current_user, vous pouvez utiliser current_user.maps.all() pour obtenir toutes les occurrences de votre modèle Map ayant une relation avec current_user.

Le documentation Django contient plus de détails.

419
Wogan

Pour ajouter à une réponse existante, un nom lié est indispensable si deux modèles FK du modèle pointent vers la même table. Par exemple en cas de nomenclature

@with_author 
class BOM(models.Model): 
    name = models.CharField(max_length=200,null=True, blank=True)
    description = models.TextField(null=True, blank=True)
    tomaterial =  models.ForeignKey(Material, related_name = 'tomaterial')
    frommaterial =  models.ForeignKey(Material, related_name = 'frommaterial')
    creation_time = models.DateTimeField(auto_now_add=True, blank=True)
    quantity = models.DecimalField(max_digits=19, decimal_places=10)

Ainsi, lorsque vous devrez accéder à ces données, vous ne pourrez utiliser que le nom associé.

 bom = material.tomaterial.all().order_by('-creation_time')

Cela ne fonctionne pas autrement (au moins, je n'ai pas pu ignorer l'utilisation du nom associé dans le cas de 2 FK dans la même table.)

66
Ilya Bibik

L'argument related_name est également utile si vous avez des noms de classe associés plus complexes. Par exemple, si vous avez une relation de clé étrangère:

class UserMapDataFrame(models.Model):
    user = models.ForeignKey(User) 

Pour accéder aux objets UserMapDataFrame à partir du User associé, l'appel par défaut serait User.usermapdataframe_set.all(), qu'il est assez difficile à lire.

L'utilisation de related_name vous permet de spécifier un nom plus simple ou plus lisible pour obtenir la relation inverse. Dans ce cas, si vous spécifiez user = models.ForeignKey(User, related_name='map_data'), l'appel sera alors User.map_data.all().

6
Daniel Holmes

Le paramètre de nom associé est en réalité une option. Si nous ne le définissons pas, Django crée automatiquement l'autre côté de la relation pour nous. Dans le cas du modèle Map, Django aurait créé un attribut map_set, permettant l'accès via m.map_set dans votre exemple (m étant votre instance de classe). La formule Django utilisée est le nom du modèle suivi de la chaîne _set. Le paramètre de nom associé remplace donc simplement la valeur par défaut de Django au lieu de fournir un nouveau comportement.

2
Abrar