通常我发现自己想要从Django中的查询集中获取第一个对象,或者如果没有't any. There are lots of ways to do this which all work. But I' m想知道哪个是最高性能的话,则返回 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
这会生成一个数据库调用,这很好 . 但是需要在很多时候创建一个异常对象,当你真正需要的只是一个简单的if-test时,这是一个非常耗费内存的事情 .
如何只使用一次数据库调用并且不使用异常对象搅拌内存?
8 回答
Django 1.6 (released Nov 2013)引入了convenience methods
first()
和last()
,如果查询集没有返回任何对象,则会吞下生成的异常并返回None
.正确的答案是
Which can be used in:
您不希望先将其转换为列表,因为这会强制对所有记录进行完整的数据库调用 . 只需执行上述操作即可完成第一项操作 . 您甚至可以使用
.order_by
来确保获得您想要的第一个 .一定要添加
.get()
否则你会得到一个QuerySet而不是一个对象 .现在,在Django 1.9中,您有查询集的
first()
方法 .这是比
.get()
或[0]
更好的方法,因为如果queryset为空,它不会抛出异常,因此,您不需要使用exists()
进行检查如果您计划经常获取第一个元素 - 您可以在此方向上扩展QuerySet:
定义这样的模型:
并像这样使用它:
它可以是这样的
要么
你应该使用django方法,比如exists . 它在那里供你使用 .
这可能也有效:
如果它为空,则返回一个空列表,否则返回列表中的第一个元素 .