在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...