You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

在Django中使用django-comments-xtd,如何返回排序后的最多评论文章?

解决Django查询评论最多文章的排序问题

问题核心是Post.published.filter(pk__in=post_ids)不会保留post_ids的原有顺序,数据库默认会按自身规则(如主键升序)返回结果。要让文章保持评论数从高到低的排序,可通过以下两种方式解决:

方案一:数据库层面自定义排序(推荐)

利用Django的Case和When构建排序规则,直接在数据库完成排序,性能更优:

from django.db.models import Case, When

@register.simple_tag
def getMostCommentedPosts(count=5):
    content_type = ContentType.objects.get_for_model(Post) 
    comment_counts = XtdComment.objects.values('object_pk').annotate(comment_count=Count('object_pk')).order_by('-comment_count')[:count]   
    post_ids = [comment['object_pk'] for comment in comment_counts]
    # 为每个post_id分配对应位置序号,按该序号排序
    ordering = Case(*[When(pk=pk, then=pos) for pos, pk in enumerate(post_ids)])
    return Post.published.filter(pk__in=post_ids).order_by(ordering)

原理

Case和When会根据post_ids的顺序,为每个文章主键分配一个递增的序号,再通过order_by让结果按这个序号升序排列,完美匹配评论数从高到低的顺序。

方案二:内存手动排序(适合小数据量)

将查询结果转为列表后,手动按post_ids的顺序重新排序:

@register.simple_tag
def getMostCommentedPosts(count=5):
    content_type = ContentType.objects.get_for_model(Post) 
    comment_counts = XtdComment.objects.values('object_pk').annotate(comment_count=Count('object_pk')).order_by('-comment_count')[:count]   
    post_ids = [comment['object_pk'] for comment in comment_counts]
    posts = list(Post.published.filter(pk__in=post_ids))
    # 按post_ids的索引位置排序
    posts.sort(key=lambda x: post_ids.index(x.pk))
    return posts

优缺点

  • 代码直观,但list.index()是O(n)操作,数据量大时效率较低,仅适合少量数据场景。

内容的提问来源于stack exchange,提问作者Owl66

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.22 15:55:05