附加到用作__in查找参数的QuerySet

时间:2013-11-01 21:45:51

标签: django django-models

我想检索用户或他/她的朋友撰写的所有帖子:

目前,我使用Q对象:

# friends = QuerySet containing User objects
# user = User object
posts = Post.objects.filter(Q(author__in=friends) | Q(author=user))

生成一个如下所示的SQL查询:

SELECT ... WHERE ("posts_post"."author_id" IN (2, 3) OR "posts_post"."author_id" = 1)

问题:

是否可以将user对象附加到friends QuerySet以生成如下所示的查询:

SELECT ... WHERE "posts_post"."author_id" IN (2, 3, 1)

直接使用QuerySet的.append()方法确实有效:

friends.append(user)
posts = Post.objects.filter(author__in=friends)

但是,我在这里和其他地方看到了许多答案,提醒我们不要将QuerySets视为基本列表。

后一种.append()技术安全吗?它是否有效,特别是如果QuerySet相当大?或者还有另一种首选方法吗?或者,随意告诉我,我很傻,Q对象方法没有错!

非常感谢。

2 个答案:

答案 0 :(得分:2)

查询集没有append方法,因此如果在您的上下文friends中工作,那么它已经是列表而不是查询集。

至于性能 - 我的直觉是,一个太大的查询集无法进入内存以便你可以附加到它上面也太大而不能像子查询一样好。但与性能问题一样,测试是唯一可靠的方法。

无论如何,你肯定会受到一些打击。如果您不需要friends其他任何内容,您可以使用values_list查询集将PK添加到内存中,附加user.id,然后过滤该PK列表。

答案 1 :(得分:1)

你可以使用这个技巧:

friends = Friend.objects.values_list('id', flat=True).order_by('id')
friends.append(user.pk)
posts = Post.objects.filter(author__in=friends)

只保存id,而不是整个查询集,这种方法非常安全。