Fix Python – .filter() vs .get() for single object? (Django)

Question

Asked By – Cory

I was having a debate on this with some colleagues. Is there a preferred way to retrieve an object in Django when you’re expecting only one?

The two obvious ways are:

try:
    obj = MyModel.objects.get(id=1)
except MyModel.DoesNotExist:
    # We have no object! Do something...
    pass

And:

objs = MyModel.objects.filter(id=1)

if len(objs) == 1:
    obj = objs[0]
else:
    # We have no object! Do something...
    pass

The first method seems behaviorally more correct, but uses exceptions in control flow which may introduce some overhead. The second is more roundabout but won’t ever raise an exception.

Any thoughts on which of these is preferable? Which is more efficient?

Now we will see solution for issue: .filter() vs .get() for single object? (Django)


Answer

get() is provided specifically for this case. Use it.

Option 2 is almost precisely how the get() method is actually implemented in Django, so there should be no “performance” difference (and the fact that you’re thinking about it indicates you’re violating one of the cardinal rules of programming, namely trying to optimize code before it’s even been written and profiled — until you have the code and can run it, you don’t know how it will perform, and trying to optimize before then is a path of pain).

This question is answered By – James Bennett

This answer is collected from stackoverflow and reviewed by FixPython community admins, is licensed under cc by-sa 2.5 , cc by-sa 3.0 and cc by-sa 4.0