Django 1.10.7在多对多字段上使用条件计数的ORM注释查询

Django 1.10.7在多对多字段上使用条件计数的ORM注释查询,django,Django,我在使用django的annnotate函数从多对多字段获取条件计数时遇到问题 我有以下三种型号: class Answer(models.Model): """ This model represents an answer to an open question. It just contains the answer text and the question it answers. """ answer_description = models.C

我在使用django的annnotate函数从多对多字段获取条件计数时遇到问题

我有以下三种型号:

class Answer(models.Model):
    """
    This model represents an answer to an open question. It just contains
    the answer text and the question it answers.
    """
    answer_description = models.CharField(max_length=1500, blank=True, null=True)
    question = models.ForeignKey(Question)
    instrument_submission = models.ForeignKey(InstrumentSubmission)

class MultipleChoiceAnswer(Answer):
    choices = models.ManyToManyField(QuestionChoice)

class QuestionChoice(models.Model):
    name = models.CharField(max_length=300)
    question = models.ForeignKey(MultipleChoiceQuestion)
    explanation_needed = models.BooleanField(default=False)
    is_correct = models.BooleanField(default=False)
    ordinal = models.IntegerField(blank=True, null=True)
    select_all = models.BooleanField(default=False)
    no_answer = models.BooleanField(default=False)
我要做的是获取所有的
多个EchoiceAnswers
,以及选项字段的总计数,以及正确选项的额外计数(具有属性
的选项是\u correct=True

例如,我有一个
multipleechoiceanswer
,它有两个相关的选项。 一个带
的是_correct=True
,另一个带
的是_correct=False

然后我运行了以下测试:

In [4]: x=MultipleChoiceAnswer.objects.filter(pk=33420)

In [11]: for ans in x:
    ...:     for c in ans.choices.all():
    ...:         print c.is_correct
    ...:         
True
False

In [7]: x=x.annotate(c=Count('choices'),
   ...: 
   ...: correct=Count('choices',filter=Q(is_correct=True)))

In [8]: for a in x:
   ...:     print a.c
   ...:     print a.correct
   ...:     
2
2
我希望看到2,然后是1。但是伯爵没有做我所期望的


有人能帮我找出问题吗?

Django 2中的聚合中添加了
filter
参数,因此它在Django 1.10中不会起任何作用。但是,您可以通过更复杂的查询实现相同的功能,该查询使用:


这基本上是将所有正确的选项相加,并为每个答案返回它们的计数。

我不确定django 2.0之前是否有注释的
filter
参数可用。无论如何,过滤器表达式应该是这样的:
Q(选项是正确的)
。我的答案是基于这些(旁注:Django 1.10是生命的终结。你应该考虑升级。)
from django.db.models import Case, Count, IntegerField, When

ans.annotate(correct=Sum(
    Case(
        When(choices__is_correct=True, then=1),
        default=0,
        output_field=IntegerField(),
    )
))