ObjectDoesNotExist与.filter().first()的比较,并检查None


在Django 1.6中,他们引入了.first()来获取查询集的第一个元素。[来源]

现在有两种方法可以获得单个元素:

user_id = 42
try:
    obj = User.objects.get(id=user_id)
except ObjectDoesNotExist:
    raise Exception("Invalid user id given")

和:

user_id = 42
obj = User.objects.filter(id=user_id).first()
if not obj:
    raise Exception("Invalid user id given")

遵循蟒蛇式的请求原谅的方式,第一种方式会更受欢迎。然而,第二个可能更容易理解,它短了一行。

Q1:这两个代码片段的速度有什么不同吗?

Q2:获取单个对象的首选方式是哪一种?

两者具有不同的语义和不同的语法。主要区别在于它们如何处理多个匹配对象。

如果多个对象与给定查询匹配,则.get()将引发异常。因此,您应该使用.get()基于唯一属性(如id(或一组属性来获取项。

如果多个对象与给定查询匹配,.first()将根据定义的顺序返回第一个项目。当您需要单个项目时,使用此选项可以筛选非唯一属性,第一个项目基于某些(可能未定义(排序。

因此,虽然.get()保证只有一个项目与查询匹配,但.first()只保证它根据给定的顺序返回第一个项目。

它们如何处理丢失的对象更多的是语义的问题。将异常转换为None或其他方式是微不足道的。虽然你可能会在这里或那里保存一行,但我不会基于此决定使用其中一行。性能差异也可以忽略不计,并且可能取决于查询的结果。

最新更新