【发布时间】:2016-01-11 19:25:20
【问题描述】:
我可能遗漏了一些明显的东西,但我无法加入 ManyToMany 字段以在 Django 应用程序中工作。我有两个模型:
class Area(models.Model):
name = CharField(...)
class Role(models.Model):
name = CharField(...)
areas = ManyToManyField('Area', ...)
我的目标是得到这个查询的等价物:
select a.name, r.name
from area a
join area_role ar on ar.area_id = a.id
join role r on ar.role_id = r.id
order by a.name, r.name
生成的数据集如下所示:
Area Role
---------------------
A My Role
A Your Role
A Yo Mamas Role
B My Role
B Some Other Role
正如您在示例中所见,我的角色 项出现了两次,每个区域一次。我知道我可以获取区域列表,然后获取每个角色的列表(导致 N+1 个查询),但如果可能的话,我希望能够高效处理。因此,我发现prefetch_related 可能是我想要使用的。但是,当我使用它时,我最终将所有区域值都设为 None。这是我尝试过的:
rqs = ( Role.objects.filter(areas__id__in=[1,2,3])
.prefetch_related(areas).order_by('areas__name', 'name') )
for r in rqs:
print("Area Name: " + str(r.areas.name))
print("Role Name: " + str(r.name))
角色名称正确地出现,但地区名称没有。我在这里做错了什么?
【问题讨论】:
-
不相关:为什么在
areas = ManyToManyField('Area', ...)的引号之间加上Area? -
print("Area Name: " + str(r.areas__name))你是说print("Area Name: " + str(r.areas.name))吗? -
@Pynchia 在这种情况下他可以使用不带引号的区域,因为区域是在角色模型之前定义的。如果在角色之后定义了区域,则需要引号。 Full explanation here
-
@danielcorreia 是的,我的意思是
r.areas.name。不知道那些双下划线是如何到达那里的......