Django get_object_or_404 or filter exists Django get_object_or_404 or filter exists django django

Django get_object_or_404 or filter exists


Using

get_object_or_404(MyModel, pk=pk)

is a shortcut for

try:    my_model = MyModel.objects.get(pk=pk)except:    raise Http404

Therefore you should only use get_object_or_404 if you want to return a 404 error when the object doesn't exist.

If you don't actually need the model object, then in theory it would be more efficient to use exists() instead of get(), because exists() doesn't actually return the object:

if not MyModel.objects.exists():    raise Http404

In practice, I'm not sure whether you would actually notice the difference. Therefore you might choose to use get_object_or_404 to make the code slightly simpler.


Using exists would be faster, but not that obvious. We can take a look at what those query do inside by logging the SQL queries:

import loggingl = logging.getLogger('django.db.backends')l.setLevel(logging.DEBUG)l.addHandler(logging.StreamHandler())User.objects.filter(pk=1).exists()get_object_or_404(User, pk=1)# (0.000) SELECT (1) AS "a" FROM "users" WHERE "users"."id" = 1 LIMIT 1; args=(1,)# (0.001) SELECT "users"."id", "users"."password", ... FROM "users" WHERE "users"."id" = 1; args=(1,)

Then the answer is obvious now. They have almost the same queries, but get_object_or_404 will get all the columns in a table while exist only take one. But this would never be a big deal.