组合从循环中获得的查询集

Posted

技术标签:

【中文标题】组合从循环中获得的查询集【英文标题】:Combining querysets obtained from a loop 【发布时间】:2012-09-11 04:40:23 【问题描述】:

假设我有一个可以“关注”的人员列表。

我想遍历某个用户关注的所有人,并以查询集的形式从所有这些用户那里获取帖子。

我知道我可以通过使用链或 | 组合查询集,但在组合查询集时我有点困惑,我可能会从被关注的每个人中循环获取。

    following = UserFollows.objects.filter(user_id = user.id)
    for follow in following.iterator():
        UserPost.objects.filter(user=follow.user) #what do I do with this?

如果我不能明确地将它们命名为链或'|',我将如何组合它们?

【问题讨论】:

【参考方案1】:

你可以这样做:

following = UserFollows.objects.filter(user__id = user.id).select_related('user')
users_ids = [follow.user.id for follow in following]
posts = UserPost.objects.filter(user__id__in=users_ids)

但是看起来这是一个相当昂贵的操作,所以最好在一个查询中添加select_related() 方法来获取用户。我认为您还应该考虑在从数据库中获取 users_ids 列表之前对其进行缓存。

【讨论】:

【参考方案2】:

你有没有尝试过类似的东西

following = UserFollows.objects.filter(user_id = user.id)
q = UserPost.objects.filter(user=following[0].user) 
for follow in following[1:]:
     q = q | UserPost.objects.filter(user=follow.user) 

【讨论】:

您知道这与下面的答案相比有多贵吗? 如果可能的话,查询集是惰性的。我现在手头没有足够小的 Django 模型,但如果 db 层实现正确,我猜它会转换为 SQL UNION 查询。可以试试吗? 我当然可以尝试,尽管我以前从未这样做过。如何测试以查看哪个更快?也许只是一个简单的计时器? 如果您使用select_related() 方法,我认为这两种解决方案在速度方面可能相同。数据库中会有两个查询:第一个是获取关注用户,第二个是获取帖子。如果您像我在回答中提到的那样缓存以下用户,则可以省略对数据库的一个查询。 数据库查询的性能调优总是很棘手,并且取决于很多细节,例如引擎(当然)以及您拥有的架构和数据。实际测量总是好的。您是否遇到性能问题?

以上是关于组合从循环中获得的查询集的主要内容,如果未能解决你的问题,请参考以下文章

怎样从生产数据库中获得想要的查询语句,把结果集批量插入到磁盘txt文件中

如何在 Python 中创建多个 for 循环列表的递归以获得组合? [复制]

如何获得两个 hasManyThrough 的组合查询

在谷歌大查询中获得完全加入,在大查询中保持所有频率组合,让我只为所有类型的加入提供左加入

Eclipse中java获得mysql的查询结果集

在Oracle中,想通过查询语句得出结果集,获得该结果集的表头。