在Django中,“ related_name”是用来做什么的?


390

related_name参数对on ManyToManyFieldForeignKeyfield有什么用?例如,给定以下代码,的作用是related_name='maps'什么?

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

12
@DanielRoseman当不需要向后关系时,使用related_name ='+'对性能或良好实践有某种意义吗?
lajarre 2012年

10
我很想知道@lajarre问题的答案。
3cheesewheel 2013年

1
@lajarre-我认为这根本不会改变性能。我不得不在FeinCMS内容类型中使用它一次。我个人认为始终指定,这是一个好习惯,related_name因此,如果您知道不使用它,我想这是一件好事。那当然是个人观点。
弗朗索瓦·恒定

@ 3cheesewheel现在在文档中:docs.djangoproject.com/en/2.0/ref/models/fields / ... +意味着不要创建反向关系
P. Myer Nore

Answers:


529

related_name属性指定从User模型回到模型的反向关系的名称。

如果不指定related_name,Django会自动使用带有后缀的型号的名称创建一个_set,例如User.map_set.all()

如果确实related_name=mapsUser模型上指定,User.map_set则仍然可以使用,但是User.maps.语法显然更简洁,更简洁。因此,例如,如果您有一个用户对象current_user,则可以current_user.maps.all()用来获取Map模型中与关联的所有实例current_user

Django文档有更多的细节。


1
好的,我知道这是旧帖子。但是我只是想弄清楚-相关名称末尾的+技巧是什么?例如,如果我related_name='maps+'在上面的示例中这样做会发生什么?
锡德2014年

10
如果添加+,django将禁用映射
josephmisiti 2014年

5
对于OneToOneField,默认related_name将为小写类名称。例如,在给定的示例中,如果成员将是OneToOnefield,则“ User.map”将起作用。
2014年

如果指定related_name_set仍然可以使用django1.11 >??
Esir Kings

9
我使用Django 2.1.3,我可以注意到它们是排他的。一旦related_name指定,将_set不再起作用。
stockersky '18

82

要添加到现有答案中-如果模型中有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。另一个并不需要。
Csaba Toth

32
related_name应该是复数。因为ForeignKey关系返回多个对象。
塔苏(Mesut Tasci)

10

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的默认值,而不提供新的行为。


0

prefetch_related用于预取多对多和多对一关系数据的数据。 select_related是从单个值关系中选择数据。这两个都用于从模型的关系中获取数据。例如,您构建一个模型以及一个与其他模型有关系的模型。当请求到来时,您还将查询他们的关系数据,并且Django具有很好的机制来从他们的关系中访问数据,例如book.author.name,当您迭代用于获取其关系数据的模型列表时,Django会为每个单个关系数据创建每个请求。为了克服这个问题,我们确实有 prefetchd_relatedselected_related

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.