Django 1.10.7在多对多字段上使用条件计数的ORM注释查询
我在使用django的annnotate函数从多对多字段获取条件计数时遇到问题 我有以下三种型号: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
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(),
)
))