检查查询是否返回任何结果的推荐习语是什么? 例子:

orgs = Organisation.objects.filter(name__iexact = 'Fjuk inc')
# If any results
    # Do this with the results without querying again.
# Else, do something else...

我想有几种不同的检查方法,但我想知道一个有经验的Django用户会怎么做。 文档中的大多数例子都忽略了什么都没有发现的情况……


当前回答

我不同意这个谓词

if not orgs:

应该是这样

if not orgs.count():

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

其他回答

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,而org .count()是250ms。在我最常见的用例中(那些有结果的用例),这种技术通常可以将时间缩短到20毫秒以下。(我找到的一个案例是6个。)

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

EDIT:如果没有找到结果,这通常会比org .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中运算符没有重载,因此在进行检查之前,结果实际上是作为列表解包的。在我的案例中,执行时间缩短了三次。