related_name 有何用途?

问题描述 投票:0回答:6

related_name
参数对
ManyToManyField
ForeignKey
字段有用吗?例如,给定以下代码,
related_name='maps'
的效果是什么?

class Map(db.Model):
    members = models.ManyToManyField(User, related_name='maps',
                                     verbose_name=_('members'))
python django foreign-keys many-to-many
6个回答
904
投票

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
设置为
"+"


158
投票

添加到现有答案 - 相关名称是必须的,以防模型中有 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 的情况下我无法跳过相关名称的使用。)


34
投票

如果您有更复杂的相关类名,则

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()


17
投票

您的问题要点如下。

既然你有

Map
User
模型,并且你已经在 Map 模型中定义了
ManyToManyField
,如果你想访问 Map 的 members 那么你可以选择
map_instance.members.all()
因为你有定义了 members 字段。 但是,假设您想要访问用户所属的所有地图,那么您有什么选择。

默认情况下,Django 为您提供了

user_instance.modelname_set.all()
,在本例中这将转换为
user.map_set.all()

mapsmap_set好得多。

lated_name 为您提供了让 Django 知道您将如何从 User 模型访问 Map 的能力,或者一般来说您如何访问反向模型,这是创建 ManyToMany 字段并在这个意义上使用 ORM 的全部要点。


5
投票

相关的name参数实际上是一个选项。如果我们不设置它,Django 自动为我们创建关系的另一面。对于 Map 模型来说, Django 会创建一个

map_set
属性,允许通过
m.map_set
进行访问 示例(m 是您的类实例)。 Django 使用的公式是模型的名称,后跟 字符串
_set
。因此,相关的名称参数只是覆盖 Django 的默认值,而不是 而不是提供新的行为。


1
投票

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

© www.soinside.com 2019 - 2024. All rights reserved.