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

Django外键关联模型查询:统计帖子点赞数并传递至前端

解决Django中批量统计帖子点赞数的问题

核心解决方案

用Django ORM的annotate()结合Count()方法,一次SQL查询就能批量统计所有帖子的点赞数,彻底避免循环单帖查询的N+1性能问题。

针对你的模型的具体实现

1. 优化模型(可选但推荐)

你的LikeMatrix模型中,post字段的related_name设为post不够直观,建议修改为likes,方便后续理解和维护:

class LikeMatrix(models.Model):
    user = models.ForeignKey(User, on_delete=models.CASCADE, related_name="liker")
    # 修改related_name为likes
    post = models.ForeignKey(Posts, on_delete=models.CASCADE, related_name="likes")

    def __str__(self):
        return f"{self.user} likes {self.post} post"

2. 视图层批量统计点赞数

在views.py中,替换原来的帖子查询代码,用annotate()给每个Posts对象添加点赞数字段:

from django.db.models import Count

def your_view(request):
    # 批量统计每个帖子的点赞数,同时提前加载关联的用户信息避免额外查询
    allPosts = Posts.objects.select_related('user')\
                            .annotate(likes_count=Count('likes'))\
                            .order_by('-id')  # 等同于原来的reverse(),写法更规范
    # 其他业务逻辑...
    return render(request, 'index.html', {'pagePosts': allPosts})

如果不修改related_name,则把Count('likes')改成Count('post')即可,因为当前post字段的related_name是post。

3. 模板中显示点赞数

把模板中所有{{post.likes}}替换为{{post.likes_count}},示例修改如下:

<!-- 原代码 -->
<label id="postLikes">{{post.likes}}</label>
<!-- 修改后 -->
<label id="postLikes">{{post.likes_count}}</label>

<!-- 其他类似位置同步修改 -->
<label id="likesNum">{{post.likes_count}}</label>

性能对比说明

  • 你之前用len(LikeMatrix.objects.filter(post=post_id))的方式,每处理一个帖子就会发起一次SQL查询,当帖子数量多的时候会产生大量重复查询,性能极低。
  • 用annotate()+Count()的方式,Django会生成一次包含分组统计的SQL查询,一次性获取所有帖子及其点赞数,性能提升显著。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.07 21:30:24