Jon*_*hop 10 python django orm
我可能会遗漏一些明显的东西,但是我无法在ManyToMany字段上加入Django应用程序.我有两个型号:
class Area(models.Model):
name = CharField(...)
class Role(models.Model):
name = CharField(...)
areas = ManyToManyField('Area', ...)
Run Code Online (Sandbox Code Playgroud)
我的目标是拥有相当于这个查询:
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
Run Code Online (Sandbox Code Playgroud)
结果数据集如下所示:
Area Role
---------------------
A My Role
A Your Role
A Yo Mamas Role
B My Role
B Some Other Role
Run Code Online (Sandbox Code Playgroud)
正如您在示例中所看到的," 我的角色"项目出现两次,每个区域出现一次.我知道我可以得到区域列表,然后获得每个区域的角色列表(产生N + 1个查询),但是如果可能的话我想要有效率.因此,我发现prefetch_related可能是我想要使用的.但是,当我使用它时,我最终将所有Area值都设置为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))
Run Code Online (Sandbox Code Playgroud)
角色名称正确用于骑行,但区域名称没有.我在这做错了什么?
无法访问r.areas__name角色r.您仍然需要通过访问角色r.areas.all().但是,通过使用prefetch_related,您可以在一个额外查询中获取所有相关对象,而不是O(n)查询.
由于您想按地区名称订购,您应该使用 Area模型用于您的查询集,然后循环执行相关角色.
areas = Area.objects.filter(id__in=[1, 2, 3]).order_by('name').prefetch_related('role_set')
for area in areas:
roles = area.role_set.all()
for role in roles:
print area.name, roles.name
Run Code Online (Sandbox Code Playgroud)
这应该为您提供所需的顺序,只要Role模型name默认排序.如果没有,您可以使用Prefetch对象来订购相关的查询集.
| 归档时间: |
|
| 查看次数: |
8868 次 |
| 最近记录: |