Im having a problem using the annnotate function of django to get a conditional count from a many to many field.
I have these 3 models:
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)
What I want to do is get all the MultipleChoiceAnswers with the total count of the choices field, and an additional count for the correct choices (the ones that have the attribute is_correct=True)
As an example, I have one MultipleChoiceAnswer that has 2 choices related.
One with is_correct=True, the other one with is_correct=False.
Then I ran the following test:
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
I would expect to see 2 and then a 1. But the Count is not doing what I expect.
Can anyone help me spot the problem?
filterargument for annotation is available before django 2.0. Either way, the filter expression should be something like this:Q(choices__is_correct). My answer is based on these docs