该related_name
参数对on ManyToManyField
和ForeignKey
field有什么用?例如,给定以下代码,的作用是related_name='maps'
什么?
class Map(db.Model):
members = models.ManyToManyField(User, related_name='maps',
verbose_name=_('members'))
回答 0
该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文档有更多的细节。
回答 1
要添加到现有答案中-如果模型中有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的情况下,我无法跳过相关名称的使用。)
回答 2
related_name
如果您具有更复杂的相关类名,则该参数也很有用。例如,如果您具有外键关系:
class UserMapDataFrame(models.Model):
user = models.ForeignKey(User)
为了UserMapDataFrame
从related中访问对象User
,默认调用为User.usermapdataframe_set.all()
,这很难阅读。
使用,related_name
您可以指定一个更简单或更清晰的名称来获取反向关系。在这种情况下,如果您指定user = models.ForeignKey(User, related_name='map_data')
,则呼叫将为User.map_data.all()
。
回答 3
相关的名称参数实际上是一个选项。如果我们不设置它,Django会自动为我们创建关系的另一面。对于Map模型,Django将创建一个map_set
属性,从而允许m.map_set
在您的示例中访问(m是您的类实例)。Django使用的公式是模型的名称,后跟字符串_set
。因此,相关的name参数仅覆盖Django的默认值,而不提供新的行为。
回答 4
prefetch_related
用于预取多对多和多对一关系数据的数据。
select_related
是从单个值关系中选择数据。这两个都用于从模型的关系中获取数据。例如,您构建一个模型以及一个与其他模型有关系的模型。当请求到来时,您还将查询他们的关系数据,并且Django具有很好的机制来从他们的关系中访问数据,例如book.author.name
,当您迭代用于获取其关系数据的模型列表时,Django会为每个单个关系数据创建每个请求。为了克服这个问题,我们确实有 prefetchd_related
和selected_related