【问题标题】:Getting Posts and its last comment in a single queryset在单个查询集中获取帖子及其最后一条评论
【发布时间】:2015-11-18 13:07:39
【问题描述】:

假设我有一个经典博客 Post 和多个相关的 Comments 模型。 我正在尝试获取每个带有最后评论的帖子列表 (或至少一个字段)。

我得到的最接近的是通过:

Post.objects.annotate(last_comment=F('comment__text'))

但这只是返回第一个推荐的正文,我明确表示 想要最后一个。

我是否遗漏了一些非常明显的东西?或者有什么聪明的方法 这样做我没看到?

【问题讨论】:

  • 有很多方法可以做到这一点。检查此相关问题并确定最适合您的问题:stackoverflow.com/questions/31234880/…
  • 从未尝试过 - 但是如果您在评论模型上指定 ordering 元属性会发生什么?
  • @MarkGalloway 遗憾的是,这里提到的最佳解决方案是保留一个冗余属性来存储最后一个Comment。这就是我现在正在做的并且想避免的事情。
  • @karthikr 这似乎工作,虽然它听起来有点像“巧合编程”的一个实例。
  • 哈哈.. 不,这不是巧合。唯一的缺点是,除了显式 order_by

标签: django django-queryset


【解决方案1】:

如果您想检索最新评论,您可能需要指定ordering on the Meta

类似这样的:

class Comment(models.Model):
   ...
   class Meta:
       ordering = ('-created_at', ) #or id, or whatever

然后,您的查询

Post.objects.annotate(last_comment=F('comment__text'))

将检索最新的帖子。

指定ordering(在这种情况下)相当于说Comments.objects.order_by('-created_at'),它总是有效的,因为你想要最新的评论。

这里有一点需要注意的是,ordering 默认应用在任何地方检索 cmets。此外,由于订购不是免费的,因此对数据库有一些影响

【讨论】:

  • 实际上,我现在已经意识到 get() 失败了,因为我似乎得到了 N 个 Posts,其中 N 是该帖子的 Comments 的数量。
  • 看起来这确实在所有情况下都按预期工作:Post.objects.distinct('id').annotate(last_comment=F('comment__text'))
  • 清除最后一条评论,使get 工作,但使filter 失败并出现SQL 错误。
猜你喜欢
  • 1970-01-01
  • 2012-07-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-03-09
  • 1970-01-01
  • 2013-05-25
相关资源
最近更新 更多