Django 是否对通过 "values()" 或 "values_list()" 访问预取的 M2M 字段进行额外查询?
Does Django makes additional query on accessing prefetched M2M field through "values()" or "values_list()"?
models.py:
class DemoA(models.Model):
M = < M2M-Field to DemoB>
class DemoB(models.Model):
title = < CharField >
查询集 预取:
qs = DemoA.objects.all().prefetch_related('M')
如 docs. 中所述,prefetch_related
与 .all()
一起使用时效果很好
例如:
# This is the expected use case and will not make any additional query
for row in qs:
print(row.M.all())
1) 现在,如果我尝试使用 .values()
或 .values_list()
方法访问它会怎样?它会进行额外的查询吗?
例如:
print(qs.values('M'))
# OR
print(qs.values_list('M'))
2) 补充:
如果我以类似的方式访问 M
的 属性 会怎样?它会进行任何额外的查询吗?
例如:
print(qs.values('M__title'))
如果在这两种情况下都进行了查询,那么进行相同操作的最佳方法是什么?循环遍历并提取它们的属性好吗?
是的。它将进行额外的查询。
原因:
"prefetched" 查询集属于 DemoB 模型class。通过row.M.all()
访问时,使用的queryset是DemoB模型class,query保持不变。而在 print(qs.values('M'))
的情况下,如果 DemoA 模型 class 使用查询集,因此构建的查询是不同的。
根据文档:
Remember that, as always with QuerySets, any subsequent chained methods which imply a different database query will ignore previously cached results, and retrieve data using a fresh database query.
models.py:
class DemoA(models.Model):
M = < M2M-Field to DemoB>
class DemoB(models.Model):
title = < CharField >
查询集 预取:
qs = DemoA.objects.all().prefetch_related('M')
如 docs. 中所述,prefetch_related
与 .all()
一起使用时效果很好
例如:
# This is the expected use case and will not make any additional query
for row in qs:
print(row.M.all())
1) 现在,如果我尝试使用 .values()
或 .values_list()
方法访问它会怎样?它会进行额外的查询吗?
例如:
print(qs.values('M'))
# OR
print(qs.values_list('M'))
2) 补充:
如果我以类似的方式访问 M
的 属性 会怎样?它会进行任何额外的查询吗?
例如:
print(qs.values('M__title'))
如果在这两种情况下都进行了查询,那么进行相同操作的最佳方法是什么?循环遍历并提取它们的属性好吗?
是的。它将进行额外的查询。
原因:
"prefetched" 查询集属于 DemoB 模型class。通过row.M.all()
访问时,使用的queryset是DemoB模型class,query保持不变。而在 print(qs.values('M'))
的情况下,如果 DemoA 模型 class 使用查询集,因此构建的查询是不同的。
根据文档:
Remember that, as always with QuerySets, any subsequent chained methods which imply a different database query will ignore previously cached results, and retrieve data using a fresh database query.