我经常发现自己想从Django的queryset中获取第一个对象,如果没有则返回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时,这是一件非常占用内存的事情。
我如何做到这一点,只有一个数据库调用,而不搅动内存与异常对象?
如果你计划经常获取第一个元素,你可以沿着这个方向扩展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)
像这样定义模型:
class MyModel(models.Model):
objects = ManagerWithFirstQuery()
像这样使用它:
first_object = MyModel.objects.filter(x=100).first()
如果你计划经常获取第一个元素,你可以沿着这个方向扩展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)
像这样定义模型:
class MyModel(models.Model):
objects = ManagerWithFirstQuery()
像这样使用它:
first_object = MyModel.objects.filter(x=100).first()