0

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

目前,我使用 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对象附加到friendsQuerySet 以生成如下所示的查询,而不是:

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 对象方法没有任何问题!

非常感谢。

4

2 回答 2

2

Querysets don't have an append method, so if that's working in your context friends is already a list rather than a queryset.

As for performance - my gut feeling is that a queryset that's too large to pull into memory so you can append to it is also going to be too large to do well as a subquery. But as always with performance questions, testing is the only real way to be sure.

You'll definitely take something of a performance hit either way. If you don't need friends for anything else, you could use a values_list queryset to get just the PKs into memory, append user.id, then filter on that list of PKs.

于 2013-11-01T21:49:53.857 回答
1

You can use this trick:

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

As far as you save only id's, not the whole queryset this method is pretty safe.

于 2013-11-01T21:55:53.333 回答