问题:在Django中,“ related_name”是用来做什么的?
该related_name
参数对on ManyToManyField
和ForeignKey
field有什么用?例如,给定以下代码,的作用是related_name='maps'
什么?
class Map(db.Model):
members = models.ManyToManyField(User, related_name='maps',
verbose_name=_('members'))
What is the related_name
argument useful for on ManyToManyField
and ForeignKey
fields? For example, given the following code, what is the effect of 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文档有更多的细节。
The related_name
attribute specifies the name of the reverse relation from the User
model back to your model.
If you don’t specify a related_name
, Django automatically creates one using the name of your model with the suffix _set
, for instance User.map_set.all()
.
If you do specify, e.g. related_name=maps
on the User
model, User.map_set
will still work, but the User.maps.
syntax is obviously a bit cleaner and less clunky; so for example, if you had a user object current_user
, you could use current_user.maps.all()
to get all instances of your Map
model that have a relation to current_user
.
The Django documentation has more details.
回答 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的情况下,我无法跳过相关名称的使用。)
To add to existing answer – related name is a must in case there 2 FKs in the model that point to the same table. For example in case of Bill of material
@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)
So when you will have to access this data
you only can use related name
bom = material.tomaterial.all().order_by('-creation_time')
It is not working otherwise (at least I was not able to skip the usage of related name in case of 2 FK’s to the same table.)
回答 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()
。
The related_name
argument is also useful if you have more complex related class names. For example, if you have a foreign key relationship:
class UserMapDataFrame(models.Model):
user = models.ForeignKey(User)
In order to access UserMapDataFrame
objects from the related User
, the default call would be User.usermapdataframe_set.all()
, which it is quite difficult to read.
Using the related_name
allows you to specify a simpler or more legible name to get the reverse relation. In this case, if you specify user = models.ForeignKey(User, related_name='map_data')
, the call would then be User.map_data.all()
.
回答 3
相关的名称参数实际上是一个选项。如果我们不设置它,Django会自动为我们创建关系的另一面。对于Map模型,Django将创建一个map_set
属性,从而允许m.map_set
在您的示例中访问(m是您的类实例)。Django使用的公式是模型的名称,后跟字符串_set
。因此,相关的name参数仅覆盖Django的默认值,而不提供新的行为。
The related name parameter is actually an option. If we do not set it, Django
automatically creates the other side of the relation for us. In the case of the Map model,
Django would have created a map_set
attribute, allowing access via m.map_set
in your
example(m being your class instance). The formula Django uses is the name of the model followed by the
string _set
. The related name parameter thus simply overrides Django’s default rather
than providing new behavior.
回答 4
prefetch_related
用于预取多对多和多对一关系数据的数据。
select_related
是从单个值关系中选择数据。这两个都用于从模型的关系中获取数据。例如,您构建一个模型以及一个与其他模型有关系的模型。当请求到来时,您还将查询他们的关系数据,并且Django具有很好的机制来从他们的关系中访问数据,例如book.author.name
,当您迭代用于获取其关系数据的模型列表时,Django会为每个单个关系数据创建每个请求。为了克服这个问题,我们确实有 prefetchd_related
和selected_related
prefetch_related
use for prefetch data for Many to many and many to one relationship data.
select_related
is to select data from a single value relationship. Both of these are used to fetch data from their relationships from a model. For example, you build a model and a model that has a relationship with other models. When a request comes you will also query for their relationship data and Django has very good mechanisms To access data from their relationship like book.author.name
but when you iterate a list of models for fetching their relationship data Django create each request for every single relationship data. To overcome this we do have prefetchd_related
and selected_related