对related_name
和ManyToManyField
字段有用的ForeignKey
参数是什么?例如,给定以下代码,related_name='maps'
的影响是什么?
class Map(db.Model):
members = models.ManyToManyField(User, related_name='maps',
verbose_name=_('members'))
答案 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)
您的问题的要点如下。
由于您拥有Map
和User
模型,并且已经在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_related
和selected_related