[英]What is related_name used for?
什么是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()
。
如果您确实指定了,例如, User
模型上的User.map_set
related_name=maps
, User.map_set
仍然有效,但User.maps.
语法显然更简洁,不那么笨重; 例如,如果您有一个用户对象current_user
,您可以使用current_user.maps.all()
来获取与current_user
有关系的Map
模型的所有实例。
Django 文档有更多细节。
要添加到现有答案 - 相关名称是必须的,以防模型中有 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
参数也很有用。 例如,如果您有外键关系:
class UserMapDataFrame(models.Model):
user = models.ForeignKey(User)
为了从相关的User
访问UserMapDataFrame
对象,默认调用将是User.usermapdataframe_set.all()
,它很难阅读。
使用related_name
允许您指定一个更简单或更清晰的名称来获得反向关系。 在这种情况下,如果您指定user = models.ForeignKey(User, related_name='map_data')
,则调用将为User.map_data.all()
。
你的问题的要点如下。
由于您有Map
和User
模型,并且您已经在 Map 模型中定义了ManyToManyField
,如果您想访问 Map 的成员,那么您可以选择map_instance.members.all()
因为您已经定义了members字段。 但是,假设您要访问用户所属的所有地图,那么您有什么选择。
默认情况下,Django会为您提供user_instance.modelname_set.all()
这将转换为user.map_set.all()
在这种情况下。
地图比map_set 好得多。
related_name为您提供了一种能力,让 Django 知道您将如何从 User 模型访问 Map 或者通常如何访问反向模型,这是创建 ManyToMany 字段和在这种意义上使用 ORM 的重点。
相关的名称参数实际上是一个选项。 如果我们不设置它,Django 会自动为我们创建关系的另一端。 在 Map 模型的情况下,Django 会创建一个map_set
属性,允许通过您的示例中的m.map_set
进行访问(m 是您的类实例)。 Django 使用的公式是模型名称后跟字符串_set
。 因此,相关的 name 参数只是覆盖了 Django 的默认值,而不是提供新的行为。
prefetch_related
用于多对多和多对一关系数据的预取数据。 select_related
是从单值关系中选择数据。 这两者都用于从模型的关系中获取数据。 例如,您构建一个模型和一个与其他模型有关系的模型。 当请求到来时,您还将查询他们的关系数据,Django 有很好的机制来访问他们关系中的数据,例如book.author.name
但是当您迭代模型列表以获取他们的关系数据时,Django 为每个请求创建每个请求关系数据。 为了克服这个问题,我们确实有prefetchd_related
和selected_related
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.