Для чего используется `related_name` в Django? - PullRequest
304 голосов
/ 15 апреля 2010

Какой аргумент related_name полезен для полей ManyToManyField и ForeignKey? Например, учитывая следующий код, каков эффект related_name='maps'?

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

Ответы [ 4 ]

406 голосов
/ 15 апреля 2010

Атрибут related_name указывает имя обратной связи от модели User к вашей модели.

Если вы не укажете related_name, Django автоматически создаст его, используя имя вашей модели с суффиксом _set, например User.map_set.all().

Если вы делаете , укажите, например, related_name=maps на модели User, User.map_set все еще будет работать, но синтаксис User.maps., очевидно, немного чище и менее неуклюж; например, если у вас есть пользовательский объект current_user, вы можете использовать current_user.maps.all(), чтобы получить все экземпляры вашей модели Map, имеющие отношение к current_user.

Документация Django содержит более подробную информацию.

65 голосов
/ 28 апреля 2016

Добавить к существующему ответу связанное имя обязательно, если в модели 2 FK, указывающих на одну и ту же таблицу.Например, в случае спецификации материала

@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)

Поэтому, когда вам потребуется доступ к этим данным, вы можете использовать только связанное имя

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

В противном случае это не работаетне удалось пропустить использование связанного имени в случае 2 FK в одной таблице.)

5 голосов
/ 13 декабря 2018

Аргумент related_name также полезен, если у вас есть более сложные связанные имена классов. Например, если у вас есть отношение внешнего ключа:

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

Чтобы получить доступ к UserMapDataFrame объектам из связанных User, вызов по умолчанию будет User.usermapdataframe_set.all(), что довольно сложно прочитать.

Использование related_name позволяет указать более простое или более разборчивое имя, чтобы получить обратную связь. В этом случае, если вы укажете user = models.ForeignKey(User, related_name='map_data'), вызов будет User.map_data.all().

2 голосов
/ 22 июля 2018

Параметр связанного имени фактически является опцией. Если мы не установим это, Джанго автоматически создает другую сторону отношения для нас. В случае модели карты, Django создал бы атрибут map_set, разрешающий доступ через m.map_set в вашем пример (твой экземпляр класса). Формула, которую использует Django, - это название модели, за которой следует Строка _set. Таким образом, связанный параметр имени просто переопределяет стандартное значение Django чем обеспечение нового поведения.

...