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

Django中SpoilerVote模型annotate返回值均为1的问题排查

问题原因及解决办法

核心问题:分组粒度太细

你这俩查询看似相似,但values()里的字段组合直接决定了分组逻辑,两者完全不同:

  • FavoriteBook的查询逻辑:
    你按book、book__book_title、book__year分组,这三个字段本质都绑定到同一个book实例(后两个是book的属性),实际分组粒度是单本图书。再加上FavoriteBook的unique_together = ['user', 'book']规则,同一本书可以被多个用户收藏,所以Count("book")能正确统计每本书的总收藏次数。

  • SpoilerVote的查询逻辑:
    你按spoiler、user、vote三个字段分组,再结合SpoilerVote的unique_together = ['spoiler', 'user']——这意味着同一个用户对同一个spoiler只能投一次票,所以spoiler+user+vote的组合在数据库里每条记录都是唯一的,每个分组里只会有1条数据,Count("spoiler")自然永远返回1。


针对不同需求的修正方案

需求1:统计每个spoiler的总投票数(不区分UP/DOWN)

去掉user和vote,只按spoiler相关字段分组:

# 统计每个spoiler的总投票数
SpoilerVote.objects.values("spoiler", "spoiler__book__book_title")  # 按需添加spoiler的关联字段
                   .annotate(count=Count("id"))
                   .order_by("-count")

需求2:统计每个spoiler的UP、DOWN分别票数

保留spoiler和vote,去掉user字段:

# 统计每个spoiler的UP/DOWN票数分布
SpoilerVote.objects.values("spoiler", "vote")
                   .annotate(count=Count("id"))
                   .order_by("-count")

小提示

用Count("id")代替Count("spoiler")更稳妥,能避免外键关联可能带来的重复计数风险,属于Django ORM统计的好习惯。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.19 18:32:35