What Is More Efficient .objects.filter().exists() Or Get() Wrapped On A Try
I'm writing tests for a django application and I want to check if an object has been saved to the database. Which is the most efficient/correct way to do it? User.objects.filter(us
Solution 1:
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.
Solution 2:
If you don't need the user, the first one is more efficient, as it doesn't instantiate the object.
Solution 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.
Post a Comment for "What Is More Efficient .objects.filter().exists() Or Get() Wrapped On A Try"