queryset.values_list 是否再次调用 db?

Does queryset.values_list makes another call to db?

假设我有一个已经评估过的查询集。

# queryset is evaluated here
queryset = MyModel.objects.filter(name="blabla")

for obj in queryset:
  # do some stuff

如果我稍后在此查询集上调用 .values_list,它会额外调用数据库还是从查询集对象缓存中获取响应?

obj_map = {k: v in queryset.values_list("id", "name")} # <- does it make a call?

检查两条语句后生成的查询表明数据库被第二次命中。试试这个:

from django.db import connection


queryset = MyModel.objects.filter(name="blabla")

for obj in queryset:
  # do some stuff
print(len(connection.queries))
>>> 1
obj_map = {k: v in queryset.values_list("id", "name")}
print(len(connection.queries))
>>> 2

您可以打印 (connection.queries) 而不是查看正在使用的实际查询。

According to the docsvalues_list 函数 returns 查询集的子类,它克隆了原始查询集的大部分属性。

在评估查询集时,它会填充用于不创建新查询集的方法的 _result_cache 属性。如果此值为None,则表示缓存为空。 此外,According to the docsvalues_list 函数 returns 是查询集的一个子类,它克隆了原始查询集的大部分属性。但是,它不会复制缓存:

print(queryset._result_cache)
# [<MyModel: 0>, <MyModel: 2>, <MyModel: 2> ... ]

print(queryset.values_list("id", "name")._result_cache)
# Nothing