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)
打印时:
reset_queries()
tc = ZModel.objects\
.filter(id=id, stock__gt=0) \
.aggregate(Sum('price'))
print(connection.queries)
我更改了字段名称以使事情保持简单。 (字段是父表的字段,即__
到多个级别)
我试图打印由Django生成并遇到connection.queries
的MySQL查询,我想知道为什么它不首先打印为空,而第二个却可以正常工作。尽管我得到了结果,但我希望得到结果。可能查询已执行。一次只执行一次。
答案 0 :(得分:1)
因为Django中的 QuerySet
是 lazy :只要您不消费,{{1 }}不进行评估:在您要获取非QuerySet
对象,例如QuerySet
,list
离子对象,dict
对象等之前,不会进行任何查询。>
但是,我们不能对所有ORM调用都执行此操作:例如Model
的对象类型为Model.objects.get(..)
,我们不能推迟获取(当然,我们可以将其包装在函数中,然后再调用它,但是“类型”是一个函数,而不是Model
实例。)
与Model
相同,因为结果是.aggregate(..)
离子,将键映射到聚合的相应结果。
但是您的第一个查询并不需要评估。通过编写切片,您只需在查询末尾添加一个dict
语句,而无需立即对其求值:该语句的类型仍为LIMIT
。
但是,如果您要在QuerySet
(list(qs)
)上调用QuerySet
,则意味着必须对qs
进行求值,并且Django会进行查询。 / p>
QuerySet
的惰性也使这些链接成为可能。想象一下您写:
QuerySet
如果将对Model.objects.filter(foo=42).filter(bar=1425)
中的QuerySet
进行立即评估,则可能会导致大量Model.objects.filter(foo=42)
实例,但是通过推迟进行计算,我们现在也可以对Model
进行过滤(我们构造了一个同时考虑了两个bar=1425
的 new QuerySet
)。这样可以使查询得到更有效的评估,例如,可以减少必须从数据库传输到Django服务器的数据。
答案 1 :(得分:0)
正如接受的答案所说您必须首先使用查询集,因为它很懒惰(例如 list(qs)
)。
它不返回任何内容的另一个原因(我的情况:)可能是:
connection.queries is only available if Django DEBUG setting is True
。