ObjectDoesNotExist与.filter()。first()并检查无

问题描述:

在Django 1.6中,他们引入了.first()以获取查询集的第一个元素。 [Source]ObjectDoesNotExist与.filter()。first()并检查无

现在有2种方式来获得一个元素:

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") 

继Python的方式来请求原谅,第一个是比较欣赏的方式使用。 然而,第二个可能更容易理解,并且缩短了一行。

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

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

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

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

.first()将基于定义的顺序返回第一个项目,如果多个对象与给定查询匹配的话。当你需要一个单独的项目时,用它来过滤非唯一的属性,第一个项目基于一些(可能未定义的)顺序。

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

他们如何处理丢失的对象更多的是语义的情况。将异常转换为None或其他方法很简单。虽然你可能会在这里和那里保存一行,但我不会根据我的决定在这个上面使用一个。性能差异也可以忽略不计,并且可能取决于查询的结果。