在Django中检查空的查询集

检查查询是否返回任何结果的推荐用法是什么?
例:

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: # Do this... else: # Do that... 

从版本1.2开始,Django具有QuerySet。 存在()方法是最有效的:

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

但是,如果您要评估QuerySet,最好使用:

 if orgs: ... 

有关更多信息,请阅读QuerySet.exists()文档 。

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

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

在一个大型的数据库项目上, not orgs orgs.count()是400+ ms, orgs.count()是250ms。 在我最常见的用例(有结果的用例)中,这个技巧通常会在20ms以下。 (我发现有一个案例是6)

当然,这可能要长得多,这取决于数据库有多远才能find结果。 甚至更快,如果它发现一个很快; 因人而异。

编辑:如果没有find结果,这通常会比orgs.count()慢,特别是如果你过滤的条件是罕见的; 因此,在需要确保视图存在或抛出Http404的视图函数中,它尤其有用。 (人们希望在哪里可以find经常存在的URL。)

要检查查询集的空白:

 if orgs.exists(): # Do something 

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

 if orgs.first(): # Do something 

我不同意这个谓词

 if not orgs: 

它应该是

 if not orgs.count(): 

我有一个相当大的结果集相同的问题(约150K结果)。 运算符在QuerySet中没有被重载,所以在做检查之前结果实际上是作为一个列表被解压缩的。 在我的情况下,执行时间减less了三个命令。

最有效的方法(在Django 1.2之前)是这样的:

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