在Django中从查询集中获取第一个对象的最快方法是什么?
我经常想从Django的查询集中获取第一个对象,如果没有的话就返回None
。有很多方法可以做到这一点,而且都能正常工作。但我在想,哪种方法性能最好。
qs = MyModel.objects.filter(blah = blah)
if qs.count() > 0:
return qs[0]
else:
return None
这样会导致两次数据库调用吗?这看起来有点浪费。这样做会更快吗?
qs = MyModel.objects.filter(blah = blah)
if len(qs) > 0:
return qs[0]
else:
return None
还有另一种选择:
qs = MyModel.objects.filter(blah = blah)
try:
return qs[0]
except IndexError:
return None
这种方法只会生成一次数据库调用,这样很好。但很多时候需要创建一个异常对象,这在内存上消耗很大,而你其实只需要做一个简单的判断。
我怎么才能只用一次数据库调用,并且不因为异常对象而浪费内存呢?
9 个回答
58
在Django 1.9中,你可以使用first()
这个方法来处理查询集。
YourModel.objects.all().first()
这个方法比.get()
或者用[0]
更好,因为如果查询集是空的,它不会抛出错误。因此,你不需要再用exists()
来检查是否有数据。
174
你可以使用 数组切片:
Entry.objects.all()[:1].get()
这可以和 .filter()
一起使用:
Entry.objects.filter()[:1].get()
你不想先把它变成一个列表,因为那样会强制从数据库中获取所有记录,这样会浪费资源。只需按照上面的做法,它只会提取第一个记录。你甚至可以使用 .order_by()
来确保你得到的是你想要的第一个记录。
486
Django 1.6(发布于2013年11月) 引入了两个非常方便的方法,分别是 first()
和 last()
。这两个方法的好处是,如果你查询的数据没有结果,它们不会报错,而是会返回 None
,也就是说返回一个空值。