Django filter versus get for single object?
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?
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).
您可以安装一个名为django-annoying的模块,然后执行此操作:
from annoying.functions import get_object_or_None
obj = get_object_or_None(MyModel, id=1)
if not obj:
#omg the object was not found do some error stuff
1 is correct. In Python an exception has equal overhead to a return. For a simplified proof you can look at this.
2 This is what Django is doing in the backend. get
calls filter
and raises an exception if no item is found or if more than one object is found.
上一篇: 我如何过滤Django中DateTimeField的日期?
下一篇: Django过滤器与获取单个对象?