Django聚合:关于关系查询集的聚合

问题描述 投票:0回答:1

假设我有以下模型,它们存储这些问题的问题和选项。

P.S:我只是在编写基本代码,只是为了给你一个想法。

class Question(models.Model):
    text = models.CharField()

class Option(models.Model):
    text = models.CharField()

class QuestionOption(models.Model):
    question = models.ForeignKey(Question)
    option = models.ForeignKey(Option)

然后我有模型存储反馈调查中为每个问题选择的用户反馈和选项。

class Feedback(models.Model):
    full_name = models.CharField()
    cell_phone = models.CharField()
    created_at = models.DateTime()

class FeedbackOption(models.Model):
    feedback = models.ForeignKey(Feedback, related_name='feedback_options')
    option = models.ForeignKey(QuestionOption)

每个反馈都会有很多反馈选项对象。现在我想过滤其反馈选项包含特定QuestionOption对象的所有反馈,然后执行聚合查询,我在检查反馈的FeedbackOptions选项文本是否为'boo'添加计数。我可以一步到位,这样的事情

# lets say i want to filter all feedback with QuestionOption id 1
stats = Feedback.objects.filter(feedback_options__option=1).aggregate(
    boo=Count(Case(When(feedback_options__option__option__text='boo', then=1))),
    hoo=Count(Case(When(feedback_options__option__option__text='hoo', then=1))))

它似乎是在唯一的反馈选项上应用聚合,其中选项id为1而不是每个反馈的其余反馈选项。

python django django-queryset
1个回答
0
投票

.filter()作为where子句。当您添加另一个方法(如.aggregate()to)生成的查询集时,它将受到相同的where子句的限制。

在Django 1.11中,您可以使用Subquery

from django.db.models import OuterRef, Subquery, Count

Feedback.objects.filter(feedback_options__option=o1).annotate(
    boo=Subquery(
        FeedbackOption.objects.filter(option__option__text="boo", feedback=OuterRef('pk')).values('feedback').annotate(count=Count('pk')).values('count'), 
        output_field=models.IntegerField())
    )

同样,您可以为hoo添加另一个注释。

Doc reference

© www.soinside.com 2019 - 2024. All rights reserved.