2

我试图在我的 django 应用程序中获得评论最多的十个帖子,但我无法做到,因为我想不出一个正确的方法。

我目前正在使用 django 评论框架,并且我已经看到了使用aggregate 或 annotate执行此操作的可能性,但我可以弄清楚如何。

事情是:

  • 获取所有帖子
  • 计算每个帖子的评论数(我有一个 comment_count 方法)
  • 将评论从评论最多的帖子排序到更少
  • 获取前 10 个(例如)

有没有“简单”或“pythonic”的方式来做到这一点?我有点迷茫,因为评论框架只能通过模板标签访问,而不是直接从代码中访问(除非你想修改它)

任何帮助表示赞赏

4

2 回答 2

3

没错,您需要使用注释和聚合功能。您需要做的是分组并计算object_pk模型的数量Comment

from django.contrib.comments.models import Comment
from django.db.models import Count

o_list = Comment.objects.values('object_pk').annotate(ocount=Count('object_pk'))

这会将类似以下的内容分配给o_list

[{'object_pk': '123', 'ocount': 56},
 {'object_pk': '321', 'ocount': 47},
 ...etc...]

然后,您可以对列表进行排序并切出前 10 个:

top_ten_objects = sorted(o_list, key=lambda k: k['ocount'])[:10]

然后,您可以使用其中的值object_pk来检索附有评论的对象。

于 2012-07-19T14:55:48.487 回答
2

Annotate 将成为首选方式,部分原因是它会减少数据库查询,而且它基本上是单行的。虽然您的理论循环会起作用,但我敢打赌,您的 comment_count 方法依赖于查询给定帖子的评论,这将是您循环过分的每个帖子的 1 个查询!

posts_by_score = Comment.objects.filter(is_public=True).values('object_pk').annotate(
    score=Count('id')).order_by('-score')
post_ids = [int(obj['object_pk']) for obj in posts_by_score]
top_posts = Post.objects.in_bulk(post_ids)

此代码无耻改编自Django-Blog-Zinnia(无从属关系)

于 2012-07-19T14:56:17.893 回答