检查Django中的空queryset

检查查询是否返回结果的推荐习语是什么?< br > 例子:< / p >

orgs = Organisation.objects.filter(name__iexact = 'Fjuk inc')
# If any results
# Do this with the results without querying again.
# Else, do something else...
我想有几种不同的方法来检查这个,但我想知道一个有经验的Django用户会怎么做。 文档中的大多数例子只是忽略了没有发现任何东西的情况…

235501 次浏览
if not orgs:
# The Queryset is empty ...
else:
# The Queryset has results ...

最有效的方法(在django 1.2之前)是:

if orgs.count() == 0:
# no results
else:
# alrigh! let's continue...

如果你有大量的对象,这可以(有时)更快:

try:
orgs[0]
# If you get here, it exists...
except IndexError:
# Doesn't exist!

在我正在处理的一个大型数据库项目中,not orgs是400+ ms, orgs.count()是250ms。在我最常见的用例中(那些有结果的用例),这种技术通常可以将时间缩短到20毫秒以下。(我找到的一个案例是6个。)

当然,可能要长得多,这取决于数据库查找结果的距离。或者更快,如果它能快速找到一个;YMMV。

编辑:如果没有找到结果,这个通常比orgs.count()慢,特别是如果你正在过滤的条件是罕见的;因此,它在需要确保视图存在或抛出Http404的视图函数中特别有用。(人们希望,在这里,人们请求的url经常是存在的。)

从1.2版开始,Django就有了QuerySet。exists()方法是最有效的:

if orgs.exists():
# Do this...
else:
# Do that...

但是如果你想对QuerySet求值,最好使用:

if orgs:
...

更多信息读取QuerySet.exists()文档

我不同意这个谓词

if not orgs:

应该是这样

if not orgs.count():

我遇到了同样的问题,一个相当大的结果集(~150k结果)。在QuerySet中运算符没有重载,因此在进行检查之前,结果实际上是作为列表解包的。在我的案例中,执行时间缩短了三次。

检查一个queryset是否为空:

if orgs.exists():
# Do something

或者你可以检查一个queryset中的第一项,如果它不存在,它将返回None:

if orgs.first():
# Do something

你也可以用这个:

< p > <代码>如果(不是(组织)): #if orgs为空 其他: #如果orgs不为空

. #