Я получаю неверные значения при подсчете аннотаций

Когда я фильтрую по одному или двум тегам, количество лайков отображается правильно. Однако если я фильтрую по трем тегам, количество лайков умножается на количество тегов, связанных с вопросом. В остальном функция работает корректно. Сами значения лайков в базе данных не меняются

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 действуют как "множители" друг друга, в результате, если вы соединяете несколько моделей, вы будете считать каждую столько раз, сколько есть совпадающих Tags.

Вы можете исправить это с помощью:

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 напрямую.

Вернуться на верх