Search code examples
sqldjangodjango-modelsdjango-rest-frameworkdjango-annotate

Django Nested Annotate


I have 3 models

class QuestionsModel(models.Model):
    created = models.DateTimeField(auto_now_add=True)
    Question = models.CharField(max_length=200)


class AnswersModel(models.Model):
    Question = models.ForeignKey(QuestionsModel, related_name='QuestionAnswer')
    Answer = models.CharField(max_length=200)


class UsersAnswerModel(models.Model):
    Answer = models.ForeignKey(AnswersModel, related_name='UsersAnswer')
    RegistrationID = models.CharField(max_length=200)


I am trying to Count How many UsersAnswer the Question

what I tried :

class DashboardAdmin(admin.ModelAdmin):
    class Meta:
        model = QuestionsModel
    change_list_template = 'admin/Dashboard_change_list.html'
    date_hierarchy = 'created'

    def has_add_permission(self, request):
        return False

    def changelist_view(self, request, extra_context=None):
        response = super().changelist_view(
            request,
            extra_context=extra_context,
        )
        try:
            qs = response.context_data['cl'].queryset
        except (AttributeError, KeyError):
            return response

        metrics = {
            'totalAnswers' : models.Count('QuestionAnswer'),
            'totalUsersAnswer' : models.Count(UsersAnswer=OuterRef('QuestionAnswer'))
        }

        response.context_data['summary'] = list(
            qs
            .values('Question')
            .annotate(**metrics)
            .order_by('-totalUsersAnswer')
        )

        return response

admin.site.register(DashboardModel, DashboardAdmin)

I could not solve

'totalUsersAnswer' : models.Count(UsersAnswer=OuterRef('QuestionAnswer'))

how to count nested foreign key

any help please


Solution

  • I have Solve it by add QuestionAnswer__UsersAnswer

    metrics = {
            'totalAnswers' : models.Count('QuestionAnswer', distinct=True),
            'totalUsersAnswer' : models.Count('QuestionAnswer__UsersAnswer'),
        }