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.