Что такое аргумент related_name
, полезный для полей ManyToManyField
и ForeignKey
? Например, учитывая следующий код, каков эффект related_name='maps'
?
class Map(db.Model):
members = models.ManyToManyField(User, related_name='maps',
verbose_name=_('members'))
Атрибут 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 содержит более подробную информацию.
related_name='maps+'
в примере выше?
Чтобы добавить к существующему ответному имени, необходимо, чтобы в модели было указано 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 в ту же таблицу.)
related_name
должно быть во множественном числе. Потому что отношения ForeignKey возвращают несколько объектов.
Параметр связанного имени фактически является опцией. Если мы не установим его, Django автоматически создаст для нас другую сторону отношения. В случае модели карты Django создал бы атрибут map_set
, разрешая доступ через m.map_set
в вашем примере (m - ваш экземпляр класса). Формула Django использует имя модели, за которой следует строка _set
. Таким образом, связанный параметр имени просто переопределяет значение по умолчанию Djangos, а не обеспечивает новое поведение.
Аргумент related_name
также полезен, если у вас есть более сложные имена связанных классов. Например, если у вас есть отношение внешнего ключа:
class UserMapDataFrame(models.Model):
user = models.ForeignKey(User)
Чтобы получить доступ UserMapDataFrame
объектам UserMapDataFrame
от связанного User
, вызов по умолчанию будет User.usermapdataframe_set.all()
, который довольно трудно прочитать.
Использование related_name
позволяет вам указать более простое или более разборчивое имя, чтобы получить обратную связь. В этом случае, если вы укажете user = models.ForeignKey(User, related_name='map_data')
, вызовом будет User.map_data.all()
.