【问题标题】:Does Django makes additional query on accessing prefetched M2M field through "values()" or "values_list()"?Django 是否对通过“values()”或“values_list()”访问预取的 M2M 字段进行附加查询?
【发布时间】:2019-05-23 19:19:57
【问题描述】:

models.py

class DemoA(models.Model):
    M = < M2M-Field to DemoB>

class DemoB(models.Model):
    title = < CharField >

查询集与预取:

qs = DemoA.objects.all().prefetch_related('M')

prefetch_related.all() 一起使用时效果很好,如docs 中所述。

例如:

# 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'))

如果在这两种情况下都进行查询,那么执行相同操作的最佳方法是什么?遍历所有并提取它们的属性是否很好?

【问题讨论】:

  • 如果您对正在运行的查询有疑问,最好的选择是使用调试工具栏:django-debug-toolbar.readthedocs.io/en/latest 该工具栏有一个 SQL 视图,显示正在执行的原始 SQL 以及执行时间SQL 调用正在进行

标签: python django python-3.x django-2.0


【解决方案1】:

是的。它将进行额外的查询。

原因:

“预取”查询集属于 DemoB 模型类。通过row.M.all()访问时,使用的查询集是DemoB模型类,查询保持不变。而在print(qs.values('M')) 的情况下,如果是 DemoA 模型类,则使用查询集,因此构建的查询是不同的。

根据文档:

请记住,与 QuerySet 一样,任何暗示不同数据库查询的后续链接方法都将忽略以前缓存的结果,并使用新的数据库查询检索数据。

【讨论】:

    猜你喜欢
    • 2014-08-26
    • 2013-05-27
    • 1970-01-01
    • 2015-01-11
    • 2017-08-01
    • 2020-11-24
    • 2014-02-11
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多