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.