related_name用于什么?

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

class Map(db.Model):
members = models.ManyToManyField(User, related_name='maps',
verbose_name=_('members'))
373235 次浏览

related_name属性指定了从User模型返回到您的模型的反向关系的名称。

如果你没有指定related_name, Django会自动创建一个带有_set后缀的模型名,例如User.map_set.all()

如果您在User模型上指定related_name=maps,则User.map_set仍然可以工作,但User.maps.语法显然更干净,不那么笨拙;例如,如果你有一个用户对象current_user,你可以使用current_user.maps.all()来获得与current_user有关系的Map模型的所有实例。

Django的文档有更多细节。

如果模型中有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的情况下跳过相关名称的使用)。

相关的name参数实际上是一个选项。如果我们不设置它,Django 自动为我们创建关系的另一端。在Map模型中, Django会创建一个map_set属性,允许通过m.map_set在你的 示例(m是你的类实例)。Django使用的公式是模型名后面跟着 # EYZ0字符串。因此,相关的name参数简单地覆盖了Django的默认值 而不是提供新的行为。

如果有更复杂的相关类名,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()

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

你问题的要点如下。

既然你有MapUser模型,你已经在地图模型中定义了ManyToManyField,如果你想访问地图的<强> < /成员强烈>,那么你有map_instance.members.all()的选项,因为你已经定义了<强> < /成员强烈>字段。 但是,如果你想访问一个用户所属的所有地图,那么你有什么选择

默认情况下,Django为你提供了user_instance.modelname_set.all(),在这种情况下,它将转换为user.map_set.all()

<强> < /地图强大>< >强map_set < / >强好得多。

related_name可以让Django知道如何从用户模型访问Map,或者如何访问反向模型,这是创建多对多字段和使用ORM的关键所在。