什么是在Django中使用的`related_name`?

时间:2010-04-15 03:51:43

标签: python django many-to-many foreign-key-relationship

related_nameManyToManyField字段有用的ForeignKey参数是什么?例如,给定以下代码,related_name='maps'的影响是什么?

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

6 个答案:

答案 0 :(得分:393)

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 documentation有更多详情。

答案 1 :(得分:64)

要添加到现有答案相关名称是必须的,以防模型中有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 :(得分:6)

您的问题的要点如下。

由于您拥有MapUser模型,并且已经在Map模型中定义了ManyToManyField,因此如果要访问 成员 < / em>,则您可以选择map_instance.members.all(),因为您已经定义了 成员 字段。 但是,假设您要访问用户的所有地图,那么您可以选择哪种方式。

默认情况下,Django为您提供了user_instance.modelname_set.all(),在这种情况下,它将转换为user.map_set.all()

地图 map_set 更好。

related_name 使您能够让Django知道如何从用户模型访问Map,或者通常如何访问反向模型,这是创建ManyToMany字段和使用ORM的全部重点在这种意义上。

答案 3 :(得分:4)

如果您具有更复杂的相关类名,则related_name自变量也很有用。例如,如果您具有外键关系:

class UserMapDataFrame(models.Model):
    user = models.ForeignKey(User) 

为了访问相关UserMapDataFrame中的User个对象,默认调用为User.usermapdataframe_set.all(),很难读取。

使用related_name可以指定一个更简单或更清晰的名称来获取反向关系。在这种情况下,如果您指定user = models.ForeignKey(User, related_name='map_data'),则呼叫将为User.map_data.all()

答案 4 :(得分:2)

相关的name参数实际上是一个选项。如果我们不设置它,Django 自动为我们创建关系的另一端。对于Map模型, Django会创建一个m.map_set属性,从而允许通过_set访问您的 示例(我是你的类实例)。 Django使用的公式是模型的名称,后跟 字符串 <input id="prodId" name="prodId" type="hidden" value=<%= i %>> 。因此,相关的名称参数仅覆盖了Django的默认值, 而不是提供新的行为。

答案 5 :(得分:0)

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