There are two simple models:
class Question(TimeStampedModel): text = models.CharField(max_length=40) class Answer(TimeStampedModel): question = models.ForeignKey(Question, related_name='answers') is_agreed = models.BooleanField() author = models.ForeingKey(User, related_name='answers')
And there is my problem:
In [18]: Question.objects.count() Out[18]: 3
I need to annotate a set of queries using the is_user_agreed and answers_amount fields:
In [18]: user = User.objects.first() In [19]: qs = Question.objects.annotate( ...: is_user_agreed=Case( ...: When(answers__in=user.answers.filter(is_agreed=True), then=Value(True)), ...: When(answers__in=user.answers.filter(is_agreed=False), then=Value(False)), ...: default=Value(None), ...: output_field=NullBooleanField(), ...: ), ...: ).annotate(answers_amount=Count('answers')) ...: qs.count() Out[19]: 4
^ here 4, but I have only 3 questions in the DB :( So, I tried with distinct()
In [20]: qs.distinct().count() Out[20]: 4
And after the last line of code, I have this exception:
NotImplementedError: annotate() + distinct(fields) is not implemented.
I also tried using this trick annotate(Count('id')).filter(id__count__gt=1)
But in this case, I lose all duplicate rows, and qs.count () is 2.
UPDATE: The problem is duplicating rows in the query set.
SOLUTION: (an expanded version of Vladimirβs second approach)
user = User.objects.first() user_agreed_questions = user.answers.filter( is_agreed=True).values_list('question_id', flat=True) user_not_agreed_questions = user.answers.filter( is_agreed=False).values_list('question_id', flat=True) Question.objects.annotate( answer_amount=Count('answers'), is_user_agreed=Case( When(id__in=user_agreed_questions, then=True), When(id__in=user_not_agreed_questions, then=False), default=None, output_field=NullBooleanField(), ), )