Leo*_*opd 177 python django performance django-models
通常我发现自己想要从Django中的查询集中获取第一个对象,或者None如果没有则返回.有很多方法可以做到这一切都有效.但我想知道哪个是性能最好的.
qs = MyModel.objects.filter(blah = blah)
if qs.count() > 0:
return qs[0]
else:
return None
Run Code Online (Sandbox Code Playgroud)
这会导致两次数据库调用吗?这似乎很浪费.这更快吗?
qs = MyModel.objects.filter(blah = blah)
if len(qs) > 0:
return qs[0]
else:
return None
Run Code Online (Sandbox Code Playgroud)
另一种选择是:
qs = MyModel.objects.filter(blah = blah)
try:
return qs[0]
except IndexError:
return None
Run Code Online (Sandbox Code Playgroud)
这会生成一个数据库调用,这很好.但是需要在很多时候创建一个异常对象,当你真正需要的只是一个简单的if-test时,这是一个非常耗费内存的事情.
如何只使用一次数据库调用并且不使用异常对象搅拌内存?
cod*_*k3y 309
Django 1.6(2013年11月发布)介绍了方便方法 first(),如果查询集没有返回任何对象last(),则会吞下生成的异常并返回None.
sto*_*ter 139
正确的答案是
Entry.objects.all()[:1].get()
Run Code Online (Sandbox Code Playgroud)
哪个可以用于:
Entry.objects.filter()[:1].get()
Run Code Online (Sandbox Code Playgroud)
您不希望先将其转换为列表,因为这会强制对所有记录进行完整的数据库调用.只需执行上述操作即可完成第一项操作.你甚至可以使用它.order_by来确保你得到你想要的第一个.
一定要添加.get()或者你将得到一个QuerySet而不是一个对象.
Ign*_*ams 49
r = list(qs[:1])
if r:
return r[0]
return None
Run Code Online (Sandbox Code Playgroud)
lev*_*evi 35
现在,在Django 1.9中,您有查询集的first() 方法.
YourModel.objects.all().first()
Run Code Online (Sandbox Code Playgroud)
这是一种更好的方式,.get()或者[0]因为如果queryset为空,它不会抛出异常,因此,您不需要检查使用exists()
如果您计划经常获取第一个元素 - 您可以在此方向上扩展QuerySet:
class FirstQuerySet(models.query.QuerySet):
def first(self):
return self[0]
class ManagerWithFirstQuery(models.Manager):
def get_query_set(self):
return FirstQuerySet(self.model)
Run Code Online (Sandbox Code Playgroud)
定义这样的模型:
class MyModel(models.Model):
objects = ManagerWithFirstQuery()
Run Code Online (Sandbox Code Playgroud)
并像这样使用它:
first_object = MyModel.objects.filter(x=100).first()
Run Code Online (Sandbox Code Playgroud)
这也可以工作:
def get_first_element(MyModel):
my_query = MyModel.objects.all()
return my_query[:1]
Run Code Online (Sandbox Code Playgroud)
如果为空,则返回一个空列表,否则返回列表中的第一个元素。
它可以是这样的
obj = model.objects.filter(id=emp_id)[0]
Run Code Online (Sandbox Code Playgroud)
要么
obj = model.objects.latest('id')
Run Code Online (Sandbox Code Playgroud)