.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
或其他方式是微不足道的。虽然你可能会在这里或那里保存一行,但我不会基于此决定使用其中一行。性能差异也可以忽略不计,并且可能取决于查询的结果。