我在使用django的annnotate函数从多个到多个字段获取条件计数时遇到了问题。
我有这3个型号:
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)
我想要做的是获取所有MultipleChoiceAnswers
选项字段的总数,以及正确选择的额外计数(具有属性is_correct=True
的那些)
作为一个例子,我有一个MultipleChoiceAnswer
有2个选择相关。
一个使用is_correct=True
,另一个使用is_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.但是伯爵并没有按照我的预期行事。
有谁能帮我发现问题?
答案 0 :(得分:3)
filter
参数被添加到Django 2中的聚合中,因此它在Django 1.10中不起作用。但是,对于使用conditional expressions的更复杂的查询,您可以实现相同的目的:
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(),
)
))
这基本上将所有正确的选项相加,并为每个答案返回它们的计数。