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所做的MySQL查询,并遇到了connection.queries
,我想知道为什么它不首先打印为空,而第二次打印则很好。虽然我得到了这个结果,但我希望这样做。可能会执行查询。也是一次只执行一个。
发布于 2018-07-26 02:53:42
因为Django中的QuerySet
**s是_惰性**:只要不对结果进行_consume,就不会对QuerySet
进行评估:不执行查询,直到您想获得非QuerySet
对象,如list
、dict
离子、Model
对象等等。
但是,对于所有ORM调用,我们都不能这样做:例如,Model.objects.get(..)
有一个Model
对象类型,我们不能推迟这个提取(当然,我们可以将它包装在一个函数中,然后稍后调用它,但是" type“是一个函数,而不是Model
实例)。
从那时起,对于一个.aggregate(..)
,结果是一个dict
,它将键映射到相应的聚合结果。
但是,不需要对第一个查询进行评估。通过编写切片,您只在查询结束时添加了一个LIMIT
语句,而不需要立即计算它:它的类型仍然是一个QuerySet
。
但是,如果要在一个list(qs)
( QuerySet
,qs
)上调用QuerySet
,那么这意味着必须对QuerySet
进行计算,Django将进行查询。
QuerySet
的懒惰也使这些链成为可能。想象一下你写的是:
Model.objects.filter(foo=42).filter(bar=1425)
如果立即评估QuerySet
of Model.objects.filter(foo=42)
,那么可能会产生大量的Model
实例,但通过推迟执行,我们现在也对bar=1425
进行筛选(我们构建了一个考虑到两个.filter(..)
的新QuerySet
)。这可能会导致查询的评估效率更高,例如,可以减少必须从数据库传输到Django服务器的数据。
发布于 2021-07-04 01:32:00
正如公认的答案所示,必须首先使用查询集,因为它很懒(例如,list(qs)
)。
另一个原因可能是您必须处于调试模式(参见常见问题):
connection.queries is only available if Django DEBUG setting is True
。
https://stackoverflow.com/questions/51537046
复制相似问题