.filter() 和 .get() 处理单个对象的区别?(Django)

175 投票
14 回答
144193 浏览
提问于 2025-04-15 12:22

我和一些同事在讨论这个问题。想知道在Django中,当你只期望得到一个对象时,有没有更好的获取方式。

有两种明显的方法:

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

还有:

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

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

第一种方法看起来在行为上更正确,但它在控制流程中使用了异常,这可能会带来一些额外的开销。第二种方法比较绕,但不会引发异常。

大家觉得这两种方法中哪种更好呢?哪种更高效呢?

14 个回答

31

你可以安装一个叫做 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
212

get() 这个方法是专门为这种情况提供的,建议你使用它。

选项2几乎就是Django中get()方法的实际实现方式,所以在性能上应该没有什么区别。而且,如果你在考虑这个问题,说明你可能违反了编程的一条重要原则,那就是在代码还没写出来、也没测试之前就想着优化代码——在你有了代码并能运行它之前,你根本不知道它的性能如何,提前优化只会让你走上痛苦的道路。

撰写回答