简体   繁体   English

Django聚合:在关系查询集上聚合

[英]Django Aggregation: Aggregate on relational queryset

Suppose I have following models, which store questions and options for those questions. 假设我有以下模型,它们存储问题和这些问题的选项。

PS: I am just writing the basic code just to give you idea. PS:我只是在写基本代码只是为了给您想法。

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)

And then I have models which store user Feedback and Options selected for each Question in the Feedback survey. 然后,我有一些模型来存储用户反馈和在“反馈”调查中为每个问题选择的选项。

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)

Every feedback will have lots of feedback option objects. 每个反馈都会有很多反馈选项对象。 Now I want to filter all the feedback whose feedback options contain specific QuestionOption object and then perform aggregate query where I am checking if that feedback's FeedbackOptions option text is 'boo' add count. 现在,我想过滤所有反馈的反馈选项包含特定的QuestionOption对象的反馈,然后执行聚合查询,在这里检查该反馈的FeedbackOptions选项文本是否为'boo'添加计数。 Can i do this in one step, Something like this 我可以一步一步做到吗,像这样

# 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))))

It looks like it's applying aggregate on the only feedback option where option id is 1 not the rest of the feedback options for each feedback. 似乎它对选项ID为1的唯一反馈选项而不是针对每个反馈的其余反馈选项应用汇总。

.filter() works as a where clause. .filter()用作where子句。 When you add another method like .aggregate() to the resulting queryset, it is bounded by the same where clause. 当向结果查询集添加另一个方法如.aggregate() ,该方法受相同的where子句限制。

In Django 1.11 you can use Subquery 在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())
    )

Similarly you can add another annotation for hoo . 同样,您可以为hoo添加另一个注释。

Doc reference 文件参考

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM