“connection.queries”在 Django 中不返回任何内容

Aas*_*wat 9 python sql django django-queryset

from django.db import connection, reset_queries

印刷: []

reset_queries()
p = XModel.objects.filter(id=id) \
.values('name') \
.annotate(quantity=Count('p_id'))\
.order_by('-quantity') \
.distinct()[:int(count)]
print(connection.queries)
Run Code Online (Sandbox Code Playgroud)

虽然这会打印:

reset_queries()
tc = ZModel.objects\
.filter(id=id, stock__gt=0) \
.aggregate(Sum('price'))
print(connection.queries)
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述

为了简单起见,我更改了字段名称。(字段是父表的,即__多级的)

我试图打印 Django 所做的 MySQL 查询并遇到了connection.queries,我想知道为什么它不打印空第一个,而第二个则工作正常。虽然我得到了我期望的结果。可能查询已被执行。而且一次只执行一个。

ica*_*ine 10

正如接受的答案所说,您必须首先使用查询集,因为它是惰性的(例如list(qs))。

另一个原因可能是您必须处于调试模式(请参阅常见问题解答
connection.queries is only available if Django DEBUG setting is True:。


Wil*_*sem 3

因为QuerySetDjango 中的 s 是惰性的:只要您不使用结果,就QuerySet不会计算结果:不会执行任何查询,直到您想要获取s、ionaries、对象等非QuerySet对象。listdictModel

然而,我们不能对所有 ORM 调用都这样做:例如,Model.objects.get(..)具有一个对象类型Model,我们不能推迟该获取(当然我们可以将它包装在一个函数中,稍后调用它,但“类型”是一个函数,而不是Model实例)。

与 a 相同,.aggregate(..)因为结果是一个dict离子,它将键映射到聚合的相应结果。

但不需要评估您的第一个查询。通过编写切片,您只LIMIT在查询末尾添加了一条语句,但不需要立即对其求值: this 的类型仍然是 a QuerySet

然而,如果您要调用list(qs)( QuerySet) qs,那么这意味着QuerySet必须对 进行求值,并且 Django 将进行查询。

s的惰性QuerySet也使得这些链接成为可能。想象一下你写:

Model.objects.filter(foo=42).filter(bar=1425)
Run Code Online (Sandbox Code Playgroud)

如果立即评估QuerySet,那么这可能会导致大量实例,但通过推迟这一点,我们现在也进行过滤(我们构建了一个将两个 s 都考虑在内的新实例。这可以导致可以更有效地评估查询,例如,可以减少必须从数据库传输到 Django 服务器的数据。Model.objects.filter(foo=42)Modelbar=1425 QuerySet.filter(..)