组合从循环中获得的查询集
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 层实现正确,我猜它会转换为 SQLUNION
查询。可以试试吗?
我当然可以尝试,尽管我以前从未这样做过。如何测试以查看哪个更快?也许只是一个简单的计时器?
如果您使用select_related()
方法,我认为这两种解决方案在速度方面可能相同。数据库中会有两个查询:第一个是获取关注用户,第二个是获取帖子。如果您像我在回答中提到的那样缓存以下用户,则可以省略对数据库的一个查询。
数据库查询的性能调优总是很棘手,并且取决于很多细节,例如引擎(当然)以及您拥有的架构和数据。实际测量总是好的。您是否遇到性能问题?以上是关于组合从循环中获得的查询集的主要内容,如果未能解决你的问题,请参考以下文章
怎样从生产数据库中获得想要的查询语句,把结果集批量插入到磁盘txt文件中
如何在 Python 中创建多个 for 循环列表的递归以获得组合? [复制]