gpt4 book ai didi

Django ORM : Retrieving posts and latest comments without performing N+1 queries

转载 作者:行者123 更新时间:2023-12-02 08:01:23 25 4
gpt4 key购买 nike

我有一个非常标准的基本社交应用程序 - 包含状态更新(即帖子)和每个帖子的多条评论。

考虑到以下简化模型,是否可以使用 Django 的 ORM 高效检索与每个帖子关联的所有帖子以及最新的两条评论,而无需执行 N+1 查询? (也就是说,无需执行单独的查询来获取页面上每个帖子的最新评论。)

class Post(models.Model):
title = models.CharField(max_length=255)
text = models.TextField()

class Comment(models.Model):
text = models.TextField()
post = models.ForeignKey(Post, related_name='comments')

class Meta:
ordering = ['-pk']

Post.objects.prefetch_lated('comments').all() 获取所有帖子和评论,但我只想检索每个帖子的有限数量的评论。

更新:

我明白,如果这可以使用 Django 的 ORM 来完成,那么可能必须使用 prefetch_lated 的某个版本来完成。多个查询完全没问题,只要我避免每页进行 N+1 次查询即可。

在 Django 中处理此问题的典型/推荐方法是什么?

更新2:

似乎没有直接且简单的方法可以通过使用 Django ORM 的简单查询来有效地完成此操作。下面的答案中有许多有用的解决方案/方法/解决方法,包括:

  • 在数据库中缓存最新的评论 ID
  • 执行原始 SQL 查询
  • 检索所有评论 ID 并在 python 中进行分组和“连接”
  • 限制您的应用程序仅显示最新评论

我不知道应该将哪一个标记为正确,因为我还没有机会尝试所有这些方法 - 但我向 hynekcer 提供了赏金,因为它提供了许多选项。

更新3:

我最终使用了@user1583799的解决方案。

最佳答案

如果您使用的是 Django 1.7,则新的 Prefetch对象(允许您自定义预取查询集)可能会很有帮助。

不幸的是,我想不出一种简单的方法来完全满足您的要求。如果您使用 PostgreSQL 并且愿意只获取每篇文章的最新评论,则以下内容应该适用于两个查询:

comments = Comment.objects.order_by('post_id', '-id').distinct('post_id')
posts = Post.objects.prefetch_related(Prefetch('comments',
queryset=comments,
to_attr='latest_comments'))

for post in posts:
latest_comment = post.latest_comments[0] if post.latest_comments else None

另一种变体:如果您的评论有时间戳,并且您希望将评论限制为按日期显示的最新评论,则类似于:

comments = Comment.objects.filter(timestamp__gt=one_day_ago)

...然后如上所述。当然,您仍然可以对结果列表进行后处理,以将显示限制为最多两条评论。

关于Django ORM : Retrieving posts and latest comments without performing N+1 queries,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26323073/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com