当我使用一两个标签进行过滤时,点赞数会正确显示。但是,如果我按三个标签进行过滤,则喜欢的数量会乘以与问题关联的标签的数量。否则,该功能将正常工作。数据库中的相似值本身不会改变
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)
模型.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'))
发生这种情况是因为 JOIN 充当彼此的“乘数”,因此,如果您在多个模型上进行 JOIN,则由于存在匹配的
Tag
,您将对每个模型进行多次计数。
您可以通过以下方式解决此问题:
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()]
questions = (
Question.objects.filter(tags__name__in=tags_list)
.annotate(likescount=Count('likes', distinct=True))
.distinct()
)
context = {'questions': questions}
return render(request, 'question/category.html', context)
也无需先获取
QuestionTags
。我们可以直接进行 JOIN。