Я получаю неверные значения при подсчете аннотаций
Когда я фильтрую по одному или двум тегам, количество лайков отображается правильно. Однако если я фильтрую по трем тегам, количество лайков умножается на количество тегов, связанных с вопросом. В остальном функция работает корректно. Сами значения лайков в базе данных не меняются
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'))
Это происходит потому, что JOIN действуют как "множители" друг друга, в результате, если вы соединяете несколько моделей, вы будете считать каждую столько раз, сколько есть совпадающих Tag
s.
Вы можете исправить это с помощью:
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 напрямую.