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

Django如何高效查询指定分类的Post列表及对应的回复数量

解决方案

一、先调整模型层配置

给ReplyPost的外键字段增加反向关联名,方便后续聚合查询:

# Model.py 修改部分
class ReplyPost(AbstractBaseModel):
    creator_id = models.ForeignKey(
        User, on_delete=models.CASCADE, related_name="reply")
    # 新增related_name参数
    post_id = models.ForeignKey(Post, on_delete=models.CASCADE, related_name="replies")
    body = models.CharField(max_length=250)

二、完整优化后的视图代码

from django.db.models import Count, F

@api_view(['GET'])
def get_most_recent_posts_by_category(request, category, count):
    # 单次查询完成过滤、聚合、字段重命名、排序、截取逻辑
    post_list = Post.objects.filter(
        goal_id__category=category
    ).annotate(
        # 聚合计算每条Post的回复数
        reply_count=Count('replies', distinct=True),
        # 直接在ORM层完成字段重命名,无需后续处理
        goal_description=F('goal_id__description'),
        post_body=F('body')
    ).order_by(
        # 按创建时间倒序,最新的在前
        '-created'
    ).values(
        # 仅返回需要的字段
        'post_body', 'goal_description', 'created', 'reply_count'
    )[:count] # 取指定条数
    # 返回列表需要加safe=False参数
    return JsonResponse(list(post_list), status=status.HTTP_200_OK, safe=False)

三、优化说明

  • 原代码存在语法错误:你将查询结果转为列表后,直接对列表做字典的键赋值/删除操作,完全无法运行,优化后直接在ORM层处理字段映射,无需额外操作
  • 解决回复数统计问题:使用Django ORM的annotate+Count做聚合,单条SQL完成所有Post的回复数统计,没有N+1查询问题,性能最优
  • 减少数据库交互:无需先单独查询匹配分类的Goal列表,直接通过跨外键过滤Post,两次查询合并为一次
  • 逻辑补齐:原代码完全没有用到传入的count参数,也没有按最新时间排序,优化后都做了对应处理
  • 返回格式合规:补充safe=False参数适配列表类型的返回值

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.05 18:06:04