related_name 的用途是什么?
related_name
这个参数在ManyToManyField
和ForeignKey
字段中有什么用呢?举个例子,假设有下面这段代码,related_name='maps'
会有什么效果呢?
class Map(db.Model):
members = models.ManyToManyField(User, related_name='maps',
verbose_name=_('members'))
6 个回答
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()
。
为了补充之前的回答,如果模型中有两个外键指向同一张表,那么使用相关名称是必须的。比如在物料清单的情况下。
@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')
否则是无法正常工作的(至少我在有两个外键指向同一张表的情况下,无法不使用相关名称)。
related_name
这个属性是用来指定从
如果你不指定related_name
,Django会自动生成一个名字,通常是你的模型名字加上后缀_set
,比如说User.map_set.all()
。
如果你指定了,比如在related_name=maps
,那么User.map_set
依然可以用,但User.maps.
这种写法显得更简洁、更好理解;举个例子,如果你有一个用户对象current_user
,你可以用current_user.maps.all()
来获取所有和current_user
有关联的Map
模型实例。
想了解更多细节,可以查看Django的文档。