[Django]-What is more efficient .objects.filter().exists() or get() wrapped on a try

33👍

Speed test: exists() vs. get() + try/except

Test functions in test.py:

from testapp.models import User

def exists(x):
    return User.objects.filter(pk=x).exists()

def get(x):
    try:
        User.objects.get(pk=x)
        return True
    except User.DoesNotExist:
        return False

Using timeit in shell:

In [1]: from testapp import test
In [2]: %timeit for x in range(100): test.exists(x)
10 loops, best of 3: 88.4 ms per loop
In [3]: %timeit for x in range(100): test.get(x)
10 loops, best of 3: 105 ms per loop
In [4]: timeit for x in range(1000): test.exists(x)
1 loops, best of 3: 880 ms per loop
In [5]: timeit for x in range(1000): test.get(x)
1 loops, best of 3: 1.02 s per loop

Conclusion: exists() is over 10% faster for checking if an object has been saved in the database.

9👍

If you don’t need the user, the first one is more efficient, as it doesn’t instantiate the object.

3👍

I would say .exists() is the better way of doing it if you’re simply trying to determine if an object matching the filter exists. The reason is because your example for .get() only covers 2 of the 3 scenarios. There’s also the MultipleObjectsReturned exception which is raised when more than 1 object is found matching the filter.

I would use .get() for fetching a single instance and use the except clauses to catch the exception workflows.

Leave a comment