zjm*_*126 339 python django many-to-many foreign-key-relationship
什么是related_name
对on ManyToManyField
和ForeignKey
字段有用的参数?例如,给出以下代码,有什么影响related_name='maps'
?
class Map(db.Model):
members = models.ManyToManyField(User, related_name='maps',
verbose_name=_('members'))
Run Code Online (Sandbox Code Playgroud)
Wog*_*gan 448
该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文档有更多的细节.
Ily*_*bik 70
要添加到现有答案相关名称是必须的,以防模型中有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)
Run Code Online (Sandbox Code Playgroud)
因此,当您必须访问此数据时,您只能使用相关名称
bom = material.tomaterial.all().order_by('-creation_time')
Run Code Online (Sandbox Code Playgroud)
它没有其他工作(至少我无法跳过相同名称的使用,如果2 FK到同一个表.)
你的问题的要点如下。
由于您拥有Map
和User
模型并且您已经ManyToManyField
在 Map 模型中定义,如果您想访问Map 的成员,那么您可以选择map_instance.members.all()
因为您已经定义了成员字段。但是,假设您要访问用户所在的所有地图,那么您有什么选择。
默认情况下,Django 为您提供user_instance.modelname_set.all()
了,user.map_set.all()
在这种情况下,这将转换为。
maps比map_set 好得多。
related_name为您提供了一种能力,让 Django 知道您将如何从 User 模型访问 Map 或者通常如何访问反向模型,这是创建 ManyToMany 字段和在这种意义上使用 ORM 的重点。
related_name
如果您具有更复杂的相关类名称,则该参数也很有用。例如,如果您具有外键关系:
class UserMapDataFrame(models.Model):
user = models.ForeignKey(User)
Run Code Online (Sandbox Code Playgroud)
为了UserMapDataFrame
从related中访问对象User
,默认调用将是User.usermapdataframe_set.all()
,这很难阅读。
使用,related_name
您可以指定一个更简单或更清晰的名称来获取反向关系。在这种情况下,如果您指定user = models.ForeignKey(User, related_name='map_data')
,则呼叫将为User.map_data.all()
。
相关的名称参数实际上是一个选项。如果我们不设置它,Django\n会自动为我们创建关系的另一端。对于 Map 模型,Django 将创建一个map_set
属性,允许通过m.map_set
您的示例(m 是您的类实例)进行访问。Django 使用的公式是模型名称后跟\n字符串_set
。因此,相关的名称参数只是覆盖 Django\xe2\x80\x99s 默认值,而不是提供新的行为。