2009-09-07 104 views
104

检查查询是否返回任何结果的推荐方法是什么?
例子:检查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的用户会怎么做。 在文档中的大多数例子只是忽略这里什么也没有找到的情况下...

回答

101
if not orgs: 
    # Do this... 
else: 
    # Do that... 
+3

这似乎在文档中也是首选,例如:https:// docs。djangoproject.com/en/1.8/topics/http/shortcuts/#id7 – Wtower 2015-05-22 09:02:08

+0

@Wtower如果过滤表达式没有命中任何记录或产生结果的“列表”,那么您引用的代码已经为合同提高了404有记录。那里的代码只会碰到一次数据库。如果他们使用'exist()'或者'count()'来检查是否有记录返回,那么他们会敲击数据库两次(一次检查,一次获取记录)。这是一个特定的情况。它不包含在*一般情况下*,知道一个查询是否会返回记录的首选方法是使用do'if queryset:...' – Louis 2015-11-03 16:26:22

+1

@Louis我引用的代码只是它包含的一个示例一行'if not my_objects:'来证明他们是如何在文档中执行的。所有其他都完全不相关,所以我不明白你的观点。他们也可以提出一千个问题,这仍然是完全不相关的,因为这不是这个答案的重点,我明确表示我同意。 – Wtower 2015-11-04 08:47:13

3

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

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

.exists()似乎更有效率 – dzida 2012-03-28 07:12:15

+3

除了.exists()在我的评论几个月后被添加,Django 1.2(包含该API)在8个月后发布。但感谢您的低投票率,并且不打扰检查事实。 – Bartosz 2012-09-12 20:26:22

+4

对不起,我在答案中添加了小编辑,使其更加准确,并且投票结果为正面。 – dzida 2012-09-13 10:10:41

14

如果你有一个庞大的数字对象,这可以(有时)要快得多:

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

在一个项目中,我正在与一个庞大的数据库,not orgs是400个+ MS和orgs.count()是25 0毫秒。在我最常见的使用情况下(有结果的情况),这种技术通常可以将这种情况降低到20毫秒以下。 (我发现有一个案例,它是6.)

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

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

134

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

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

但是,如果你要评估的QuerySet无论如何,它是更好地使用:

if orgs: 
    ... 

欲了解更多信息read QuerySet.exists() documentation

5

我与谓词

if not orgs: 

不同意它应该是

if not orgs.count(): 

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

+4

_ \ _非零_ _已在QuerySet中重载。如果结果没有被缓存(它从来不是第一次使用queryset),_ \ _非零_ \ _的行为是迭代queryset中的所有元素。如果集合很大,这是非常糟糕的。 – hedleyroos 2011-07-30 15:45:22

9

要检查查询集的空虚:

if orgs.exists(): 
    # Do something 

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

if orgs.first(): 
    # Do something 
+1

'如果orgs.exists()'覆盖了大约5年前提供的[答案](http://stackoverflow.com/a/2373793/1906307)。这个答案带来的唯一的事情就是org.first()'。 (即使这是有争议的:大约5年前与做orgs [0]'[建议](http://stackoverflow.com/a/2098092/1906307)有很大区别吗?)你应该开发那部分答案是:什么时候想要这样做而不是**早先提出的其他解决方案? – Louis 2015-11-03 16:33:22