Django查询集过滤的等价性

时间:2016-06-19 12:09:06

标签: django django-models django-queryset

我在Django项目中交替使用以下两个:

Comments.objects.filter(writer=self.request.user).latest('id')

Comments.objects.get(writer=self.request.user)

它们在实践中是否相同? docs似乎没有明确解决此问题。

3 个答案:

答案 0 :(得分:0)

我不知道为什么你会认为这些是等价的,或者为什么文档应该具体解决这个问题。

如果您只有一个匹配的评论,那么这将给出相同的结果。但是第一个版本将通过更复杂的查询来完成,并在id上添加了一个排序。

如果您对该作者有多个评论 - 似乎很可能 - 第二个版本将始终给出MultipleObjectsReturned错误。

答案 1 :(得分:0)

它们根本不相同,但这在很大程度上取决于特定的型号。我们不知道您的模型Comments的详细信息,但如果我们假设该字段编写器不是唯一的:

第一个声明:

Comments.objects.filter(writer=self.request.user).latest('id')

本质上返回具有特定writer的所有注释的查询集中具有最大id的对象。如果查看django.db.connections['default'].queries,则会看到生成的查询是SELECT .. ORDER_BY .. LIMIT ..语句。

对于第二个陈述:

Comments.objects.get(writer=self.request.user)

返回该作者的特定记录。如果有多个,则会出现MultipleObjectsReturned异常。如果未找到任何对象,则会出现DoesNotExist异常。如果这是一个唯一的字段,或者偶然会有一个对象,那么生成的查询将是SELECT .. WHERE语句更快。

关于文档,如果您查看Options.get_latest_by引用,可以获得有关latest函数用途的更多信息。想想它更多是Django提供的便利。尽管如此,理解Django如何评估查询和生成的SQL仍然非常重要,并且总有很多方法可以实现相同的查询,因此这是逻辑问题。

答案 2 :(得分:0)

filter给出与您的过滤器对应的所有行。

latest提供最近一行(最高ID值)

例如:

Comments.objects.filter(writer=self.request.user).latest('id')首先获得Comments撰写的所有self.request.user,然后latest获取最新信息。

get是为了得到一条唯一的行,所以:

Comments.objects.get(writer=self.request.user)会给出self.request.user撰写的评论。应该只有一个。如果用户可以撰写许多评论,那么您必须使用filterall。这取决于你想要什么。

更多信息here