Fastest way to get the first object from a queryset in django?
Often I find myself wanting to get the first object from a queryset in Django, or return None if there aren't any. There are lots of ways to do this which all work. But I'm wondering which is the most performant. qs = MyModel.objects.filter(blah = blah) if qs.count() > 0: return qs else: return None Does this result in two database calls? That seems wasteful. Is this any faster? qs = MyModel.objects.filter(blah = blah) if len(qs) > 0: return qs else: return None Another option would be: qs = MyModel.objects.filter(blah = blah) try: return qs except IndexError: return None This generates a single database call, which is good. But requires creating an exception object a lot of the time, which is a very memory-intensive thing to do when all you really need is a trivial if-test. How can I do this with just a single database call and without churning memory with exception objects?
The correct answer is
Which can be used in:
You wouldn’t want to first turn it into a list because that would force a full database call of all the records. Just do the above and it will only pull the first. You could even use
.order_by to ensure you get the first you want.
Be sure to add the
.get() or else you will get a QuerySet back and not an object.
r = list(qs[:1]) if r: return r return None
Now, in Django 1.9 you have
first() method for querysets.
This is a better way than
 because it does not throw an exception if queryset is empty, Therafore, you don’t need to check using
If you plan to get first element often – you can extend QuerySet in this direction:
class FirstQuerySet(models.query.QuerySet): def first(self): return self class ManagerWithFirstQuery(models.Manager): def get_query_set(self): return FirstQuerySet(self.model)
Define model like this:
class MyModel(models.Model): objects = ManagerWithFirstQuery()
And use it like this:
first_object = MyModel.objects.filter(x=100).first()
It can be like this
obj = model.objects.filter(id=emp_id)
obj = model.objects.latest('id')
This could work as well:
def get_first_element(MyModel): my_query = MyModel.objects.all() return my_query[:1]
if it’s empty, then returns an empty list, otherwise it returns the first element inside a list.
You should use django methods, like exists. Its there for you to use it.
if qs.exists(): return qs return None
Since django 1.6 you can use filter() with first() method like so:
- Database Administration Tutorials
- Programming Tutorials & IT News
- Linux & DevOps World
- Entertainment & General News
- Games & eSport