繁体   English   中英

什么是related_name 用于?

[英]What is related_name used for?

什么是related_name上有用的参数ManyToManyFieldForeignKey领域? 例如,给定以下代码, 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=mapsUser.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()

你的问题的要点如下。

由于您有MapUser模型,并且您已经在 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_relatedselected_related

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM