related_name 有什么用?
- 2024-12-04 08:56:00
- admin 原创
- 156
问题描述:
related_name
对ManyToManyField
和字段有用的参数是什么ForeignKey
?例如,给定以下代码,的效果是什么related_name='maps'
?
class Map(db.Model):
members = models.ManyToManyField(User, related_name='maps',
verbose_name=_('members'))
解决方案 1:
该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 文档有更多详细信息。
要完全禁用创建向后关系,请设置related_name
为"+"
。
解决方案 2:
如果模型中有 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 到同一张表的情况下我无法跳过相关名称的使用。)
解决方案 3:
如果您有更复杂的相关类名,该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:
您的问题主要如下。
由于您有Map
和User
模型,并且已经在 Map 模型中定义ManyToManyField
,如果您想访问Map 的成员,那么您可以选择,map_instance.members.all()
因为您已经定义了成员字段。但是,假设您想访问用户所属的所有地图,那么您有什么选择。
默认情况下,Django 为您提供了user_instance.modelname_set.all()
,在这种情况下这将转换为user.map_set.all()
。
map比map_set好得多。
related_name为您提供了一种能力,可以让 Django 知道如何从 User 模型访问 Map,或者通常知道如何访问反向模型,这是创建 ManyToMany 字段并使用 ORM 的全部意义所在。
解决方案 5:
相关名称参数实际上是一个选项。如果我们不设置它,Django 会自动为我们创建关系的另一侧。在 Map 模型的情况下,Django 将创建一个map_set
属性,允许通过m.map_set
您的示例中的访问(m 是您的类实例)。Django 使用的公式是模型的名称后跟字符串_set
。因此,相关名称参数只是覆盖了 Django 的默认值,而不是提供新的行为。
解决方案 6:
prefetch_related
用于预取多对多和多对一关系数据。select_related
是从单值关系中选择数据。这两者都用于从模型的关系中获取数据。例如,您构建一个模型和一个与其他模型有关系的模型。当收到请求时,您还将查询它们的关系数据,并且 Django 具有非常好的机制来从它们的关系中访问数据,book.author.name
但是当您迭代模型列表以获取它们的关系数据时,Django 会为每个关系数据创建每个请求。为了克服这个问题,我们确实 prefetchd_related
有selected_related