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

多标签过滤时Question点赞数统计异常问题求助

问题描述

当使用1个或2个标签过滤Question时,点赞数显示正确;但使用3个标签过滤时,点赞数会被该Question关联的标签数量相乘,数据库中的点赞数据本身并未发生变化。

相关代码

视图函数代码

def tagAndFilter(request):
    tags_string = request.GET.get('tags', None)
    
    if tags_string:
        tags_list = [tag.strip() for tag in tags_string.split(',') if tag.strip()]

        tags = QuestionTag.objects.filter(name__in=tags_list)
        
        questions = Question.objects.filter(tags__in=tags).distinct()
        
        questions = questions.annotate(likescount=Count('likes'))

    context = {
        'questions': questions
    }
    return render(request, 'question/category.html', context)

models.py代码

class Like(models.Model):
    user = models.ForeignKey(User, on_delete=models.CASCADE)
    question = models.ForeignKey(Question, on_delete=models.CASCADE, related_name='likes')
    created_at = models.DateTimeField(auto_now_add=True)
问题分析与解决方案

你指出的questions = questions.annotate(likescount=Count('likes'))确实是问题所在。

原因

当通过多个标签过滤Question时,Django ORM会生成多表关联查询:一个关联了N个目标标签的Question,会在关联后的查询结果集中出现N次。虽然你调用了distinct()对Question去重,但annotate的计数逻辑是基于关联后的重复行执行的,这就导致点赞数被乘以该Question关联的标签数量。

解决方案

有两种可行的修复方式:

方式1:给Count添加distinct参数

直接在Count中指定distinct=True,确保只对唯一的点赞记录计数:

questions = questions.annotate(likescount=Count('likes', distinct=True))

这种方式简洁高效,优先推荐。

方式2:使用子查询统计点赞数

通过子查询单独统计每个Question的点赞数,避免多表关联带来的重复计数问题:

from django.db.models import Subquery, OuterRef

# 子查询:统计单个Question的点赞数
likes_subquery = Like.objects.filter(question=OuterRef('pk')).values('question').annotate(count=Count('id')).values('count')
questions = questions.annotate(likescount=Subquery(likes_subquery))

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.27 14:37:33