prompt: We are currently solving the following issue within our repository. Here is the issue text:
  --- BEGIN ISSUE ---
  MultipleObjectsReturned: get() returned more than one Lesson -- it returned 2!
  Sentry Issue: [KOLIBRI-BACKEND-7](https://sentry.io/learningequality/kolibri-backend/issues/877453921/?referrer=github_integration)
  
  ```
  MultipleObjectsReturned: get() returned more than one Lesson -- it returned 2!
  (8 additional frame(s) were not displayed)
  ...
    File "rest_framework/mixins.py", line 56, in retrieve
      instance = self.get_object()
    File "rest_framework/generics.py", line 98, in get_object
      obj = get_object_or_404(queryset, **filter_kwargs)
    File "rest_framework/generics.py", line 21, in get_object_or_404
      return _get_object_or_404(queryset, *filter_args, **filter_kwargs)
    File "django/shortcuts.py", line 85, in get_object_or_404
      return queryset.get(*args, **kwargs)
    File "django/db/models/query.py", line 384, in get
      (self.model._meta.object_name, num)
  ```
  
  --- END ISSUE ---
  
  Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
  --- BEGIN FILES ---
  Path: `kolibri/plugins/learn/viewsets.py`
  Content:
  ```
  1 from django.db.models.query import F
  2 from rest_framework.permissions import IsAuthenticated
  3 from rest_framework.viewsets import ReadOnlyModelViewSet
  4 
  5 from .serializers import LearnerClassroomSerializer
  6 from kolibri.core.auth.api import KolibriAuthPermissionsFilter
  7 from kolibri.core.auth.filters import HierarchyRelationsFilter
  8 from kolibri.core.auth.models import Classroom
  9 from kolibri.core.lessons.models import Lesson
  10 from kolibri.core.lessons.models import LessonAssignment
  11 from kolibri.core.lessons.serializers import LessonSerializer
  12 
  13 
  14 class LearnerClassroomViewset(ReadOnlyModelViewSet):
  15     """
  16     Returns all Classrooms for which the requesting User is a member,
  17     along with all associated assignments.
  18     """
  19     filter_backends = (KolibriAuthPermissionsFilter,)
  20     permission_classes = (IsAuthenticated,)
  21     serializer_class = LearnerClassroomSerializer
  22 
  23     def get_queryset(self):
  24         current_user = self.request.user
  25         memberships = current_user.memberships.filter(
  26             collection__kind='classroom',
  27         ).values('collection_id')
  28         return Classroom.objects.filter(id__in=memberships)
  29 
  30 
  31 class LearnerLessonViewset(ReadOnlyModelViewSet):
  32     """
  33     Special Viewset for Learners to view Lessons to which they are assigned.
  34     The core Lesson Viewset is locked down to Admin users only.
  35     """
  36     serializer_class = LessonSerializer
  37     permission_classes = (IsAuthenticated,)
  38 
  39     def get_queryset(self):
  40         assignments = HierarchyRelationsFilter(LessonAssignment.objects.all()) \
  41             .filter_by_hierarchy(
  42                 target_user=self.request.user,
  43                 ancestor_collection=F('collection')
  44         )
  45         return Lesson.objects.filter(
  46             lesson_assignments__in=assignments,
  47             is_active=True
  48         )
  49
  ```
  
  Path: `kolibri/plugins/learn/serializers.py`
  Content:
  ```
  1 from django.db.models import Q
  2 from django.db.models import Sum
  3 from rest_framework.serializers import JSONField
  4 from rest_framework.serializers import ModelSerializer
  5 from rest_framework.serializers import SerializerMethodField
  6 
  7 from kolibri.core.auth.models import Classroom
  8 from kolibri.core.exams.models import Exam
  9 from kolibri.core.lessons.models import Lesson
  10 from kolibri.core.logger.models import ContentSummaryLog
  11 from kolibri.core.logger.models import ExamLog
  12 
  13 
  14 class ExamProgressSerializer(ModelSerializer):
  15     """
  16     Annotates an Exam with progress information based on logs generated
  17     by the requesting User
  18     """
  19     class Meta:
  20         model = Exam
  21         fields = (
  22             'active',
  23             'id',
  24             'progress',
  25             'question_count',
  26             'title',
  27         )
  28 
  29     progress = SerializerMethodField()
  30 
  31     # Mostly copied from UserExamSerializer.to_representation, but working directly
  32     # from Exam Model instead of ExamAssignment
  33     def get_progress(self, instance):
  34         try:
  35             examlogs = instance.examlogs.get(user=self.context['user'])
  36             return {
  37                 'score': examlogs.attemptlogs.aggregate(Sum('correct')).get('correct__sum'),
  38                 'answer_count': examlogs.attemptlogs.count(),
  39                 'closed': examlogs.closed,
  40             }
  41         except ExamLog.DoesNotExist:
  42             return {
  43                 'score': None,
  44                 'answer_count': None,
  45                 'closed': None,
  46             }
  47 
  48 
  49 class LessonProgressSerializer(ModelSerializer):
  50     """
  51     Annotates a Lesson with progress information based on logs generated
  52     by the requesting User
  53     """
  54     progress = SerializerMethodField()
  55     resources = JSONField(default='[]')
  56 
  57     class Meta:
  58         model = Lesson
  59         fields = (
  60             'description',
  61             'id',
  62             'is_active',
  63             'title',
  64             'progress',
  65             'resources',
  66         )
  67 
  68     def get_progress(self, instance):
  69         content_ids = [resource['content_id'] for resource in instance.resources]
  70         resource_progress = ContentSummaryLog.objects \
  71             .filter(
  72                 user=self.context['user'],
  73                 content_id__in=content_ids
  74             ) \
  75             .aggregate(Sum('progress')).get('progress__sum')
  76         return {
  77             'resource_progress': resource_progress,
  78             'total_resources': len(instance.resources),
  79         }
  80 
  81 
  82 class LearnerClassroomSerializer(ModelSerializer):
  83     assignments = SerializerMethodField()
  84 
  85     class Meta:
  86         model = Classroom
  87         fields = (
  88             'id',
  89             'name',
  90             'assignments',
  91         )
  92 
  93     def get_assignments(self, instance):
  94         """
  95         Returns all Exams and Lessons (and progress) assigned to the requesting User
  96         """
  97         current_user = self.context['request'].user
  98         memberships = current_user.memberships.all()
  99         learner_groups = [m.collection for m in memberships]
  100 
  101         # Return only active Lessons that are assigned to the requesting user's groups
  102         # TODO move this to a permission_class on Lesson
  103         filtered_lessons = Lesson.objects.filter(
  104             lesson_assignments__collection__in=learner_groups,
  105             collection=instance,
  106             is_active=True,
  107         ).distinct()
  108 
  109         filtered_exams = Exam.objects.filter(
  110             assignments__collection__in=learner_groups,
  111             collection=instance,
  112         ).filter(Q(active=True) | Q(examlogs__user=current_user)).distinct()
  113 
  114         return {
  115             'lessons': LessonProgressSerializer(
  116                 filtered_lessons,
  117                 many=True,
  118                 context={'user': current_user},
  119             ).data,
  120             'exams': ExamProgressSerializer(
  121                 filtered_exams,
  122                 many=True,
  123                 context={'user': current_user},
  124             ).data,
  125         }
  126
  ```
  --- END FILES ---
  
  Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.
  
  Here is an example:
  
  ```diff
  diff --git a/examples/server_async.py b/examples/server_async.py
  --- a/examples/server_async.py
  +++ b/examples/server_async.py
  @@ -313,4 +313,4 @@
   
   
   if __name__ == "__main__":
  -    asyncio.run(run_async_server("."), debug=True)
  +    asyncio.run(run_async_server(), debug=True)
  diff --git a/examples/server_sync.py b/examples/server_sync.py
  --- a/examples/server_sync.py
  +++ b/examples/server_sync.py
  @@ -313,5 +313,5 @@
   
   
   if __name__ == "__main__":
  -    server = run_sync_server(".")
  +    server = run_sync_server()
       server.shutdown()
  
  ```
  
golden_diff: diff --git a/kolibri/plugins/learn/serializers.py b/kolibri/plugins/learn/serializers.py
  --- a/kolibri/plugins/learn/serializers.py
  +++ b/kolibri/plugins/learn/serializers.py
  @@ -4,9 +4,12 @@
   from rest_framework.serializers import ModelSerializer
   from rest_framework.serializers import SerializerMethodField
   
  +from kolibri.core.auth.filters import HierarchyRelationsFilter
   from kolibri.core.auth.models import Classroom
   from kolibri.core.exams.models import Exam
  +from kolibri.core.exams.models import ExamAssignment
   from kolibri.core.lessons.models import Lesson
  +from kolibri.core.lessons.models import LessonAssignment
   from kolibri.core.logger.models import ContentSummaryLog
   from kolibri.core.logger.models import ExamLog
   
  @@ -95,19 +98,27 @@
           Returns all Exams and Lessons (and progress) assigned to the requesting User
           """
           current_user = self.context['request'].user
  -        memberships = current_user.memberships.all()
  -        learner_groups = [m.collection for m in memberships]
   
           # Return only active Lessons that are assigned to the requesting user's groups
           # TODO move this to a permission_class on Lesson
  +        lesson_assignments = HierarchyRelationsFilter(LessonAssignment.objects.all()) \
  +            .filter_by_hierarchy(
  +                target_user=current_user,
  +                ancestor_collection=instance
  +        )
           filtered_lessons = Lesson.objects.filter(
  -            lesson_assignments__collection__in=learner_groups,
  -            collection=instance,
  -            is_active=True,
  +            lesson_assignments__in=lesson_assignments,
  +            is_active=True
           ).distinct()
   
  +        exam_assignments = HierarchyRelationsFilter(ExamAssignment.objects.all()) \
  +            .filter_by_hierarchy(
  +                target_user=current_user,
  +                ancestor_collection=instance
  +        )
  +
           filtered_exams = Exam.objects.filter(
  -            assignments__collection__in=learner_groups,
  +            assignments__in=exam_assignments,
               collection=instance,
           ).filter(Q(active=True) | Q(examlogs__user=current_user)).distinct()
   
  diff --git a/kolibri/plugins/learn/viewsets.py b/kolibri/plugins/learn/viewsets.py
  --- a/kolibri/plugins/learn/viewsets.py
  +++ b/kolibri/plugins/learn/viewsets.py
  @@ -21,11 +21,10 @@
       serializer_class = LearnerClassroomSerializer
   
       def get_queryset(self):
  -        current_user = self.request.user
  -        memberships = current_user.memberships.filter(
  -            collection__kind='classroom',
  -        ).values('collection_id')
  -        return Classroom.objects.filter(id__in=memberships)
  +        return HierarchyRelationsFilter(Classroom.objects.all()).filter_by_hierarchy(
  +            target_user=self.request.user,
  +            ancestor_collection=F('id')
  +        )
   
   
   class LearnerLessonViewset(ReadOnlyModelViewSet):
  @@ -45,4 +44,4 @@
           return Lesson.objects.filter(
               lesson_assignments__in=assignments,
               is_active=True
  -        )
  +        ).distinct()
  
verification_info: {"golden_diff": "diff --git a/kolibri/plugins/learn/serializers.py b/kolibri/plugins/learn/serializers.py\n--- a/kolibri/plugins/learn/serializers.py\n+++ b/kolibri/plugins/learn/serializers.py\n@@ -4,9 +4,12 @@\n from rest_framework.serializers import ModelSerializer\n from rest_framework.serializers import SerializerMethodField\n \n+from kolibri.core.auth.filters import HierarchyRelationsFilter\n from kolibri.core.auth.models import Classroom\n from kolibri.core.exams.models import Exam\n+from kolibri.core.exams.models import ExamAssignment\n from kolibri.core.lessons.models import Lesson\n+from kolibri.core.lessons.models import LessonAssignment\n from kolibri.core.logger.models import ContentSummaryLog\n from kolibri.core.logger.models import ExamLog\n \n@@ -95,19 +98,27 @@\n         Returns all Exams and Lessons (and progress) assigned to the requesting User\n         \"\"\"\n         current_user = self.context['request'].user\n-        memberships = current_user.memberships.all()\n-        learner_groups = [m.collection for m in memberships]\n \n         # Return only active Lessons that are assigned to the requesting user's groups\n         # TODO move this to a permission_class on Lesson\n+        lesson_assignments = HierarchyRelationsFilter(LessonAssignment.objects.all()) \\\n+            .filter_by_hierarchy(\n+                target_user=current_user,\n+                ancestor_collection=instance\n+        )\n         filtered_lessons = Lesson.objects.filter(\n-            lesson_assignments__collection__in=learner_groups,\n-            collection=instance,\n-            is_active=True,\n+            lesson_assignments__in=lesson_assignments,\n+            is_active=True\n         ).distinct()\n \n+        exam_assignments = HierarchyRelationsFilter(ExamAssignment.objects.all()) \\\n+            .filter_by_hierarchy(\n+                target_user=current_user,\n+                ancestor_collection=instance\n+        )\n+\n         filtered_exams = Exam.objects.filter(\n-            assignments__collection__in=learner_groups,\n+            assignments__in=exam_assignments,\n             collection=instance,\n         ).filter(Q(active=True) | Q(examlogs__user=current_user)).distinct()\n \ndiff --git a/kolibri/plugins/learn/viewsets.py b/kolibri/plugins/learn/viewsets.py\n--- a/kolibri/plugins/learn/viewsets.py\n+++ b/kolibri/plugins/learn/viewsets.py\n@@ -21,11 +21,10 @@\n     serializer_class = LearnerClassroomSerializer\n \n     def get_queryset(self):\n-        current_user = self.request.user\n-        memberships = current_user.memberships.filter(\n-            collection__kind='classroom',\n-        ).values('collection_id')\n-        return Classroom.objects.filter(id__in=memberships)\n+        return HierarchyRelationsFilter(Classroom.objects.all()).filter_by_hierarchy(\n+            target_user=self.request.user,\n+            ancestor_collection=F('id')\n+        )\n \n \n class LearnerLessonViewset(ReadOnlyModelViewSet):\n@@ -45,4 +44,4 @@\n         return Lesson.objects.filter(\n             lesson_assignments__in=assignments,\n             is_active=True\n-        )\n+        ).distinct()\n", "issue": "MultipleObjectsReturned: get() returned more than one Lesson -- it returned 2!\nSentry Issue: [KOLIBRI-BACKEND-7](https://sentry.io/learningequality/kolibri-backend/issues/877453921/?referrer=github_integration)\n\n```\nMultipleObjectsReturned: get() returned more than one Lesson -- it returned 2!\n(8 additional frame(s) were not displayed)\n...\n  File \"rest_framework/mixins.py\", line 56, in retrieve\n    instance = self.get_object()\n  File \"rest_framework/generics.py\", line 98, in get_object\n    obj = get_object_or_404(queryset, **filter_kwargs)\n  File \"rest_framework/generics.py\", line 21, in get_object_or_404\n    return _get_object_or_404(queryset, *filter_args, **filter_kwargs)\n  File \"django/shortcuts.py\", line 85, in get_object_or_404\n    return queryset.get(*args, **kwargs)\n  File \"django/db/models/query.py\", line 384, in get\n    (self.model._meta.object_name, num)\n```\n", "before_files": [{"content": "from django.db.models.query import F\nfrom rest_framework.permissions import IsAuthenticated\nfrom rest_framework.viewsets import ReadOnlyModelViewSet\n\nfrom .serializers import LearnerClassroomSerializer\nfrom kolibri.core.auth.api import KolibriAuthPermissionsFilter\nfrom kolibri.core.auth.filters import HierarchyRelationsFilter\nfrom kolibri.core.auth.models import Classroom\nfrom kolibri.core.lessons.models import Lesson\nfrom kolibri.core.lessons.models import LessonAssignment\nfrom kolibri.core.lessons.serializers import LessonSerializer\n\n\nclass LearnerClassroomViewset(ReadOnlyModelViewSet):\n    \"\"\"\n    Returns all Classrooms for which the requesting User is a member,\n    along with all associated assignments.\n    \"\"\"\n    filter_backends = (KolibriAuthPermissionsFilter,)\n    permission_classes = (IsAuthenticated,)\n    serializer_class = LearnerClassroomSerializer\n\n    def get_queryset(self):\n        current_user = self.request.user\n        memberships = current_user.memberships.filter(\n            collection__kind='classroom',\n        ).values('collection_id')\n        return Classroom.objects.filter(id__in=memberships)\n\n\nclass LearnerLessonViewset(ReadOnlyModelViewSet):\n    \"\"\"\n    Special Viewset for Learners to view Lessons to which they are assigned.\n    The core Lesson Viewset is locked down to Admin users only.\n    \"\"\"\n    serializer_class = LessonSerializer\n    permission_classes = (IsAuthenticated,)\n\n    def get_queryset(self):\n        assignments = HierarchyRelationsFilter(LessonAssignment.objects.all()) \\\n            .filter_by_hierarchy(\n                target_user=self.request.user,\n                ancestor_collection=F('collection')\n        )\n        return Lesson.objects.filter(\n            lesson_assignments__in=assignments,\n            is_active=True\n        )\n", "path": "kolibri/plugins/learn/viewsets.py"}, {"content": "from django.db.models import Q\nfrom django.db.models import Sum\nfrom rest_framework.serializers import JSONField\nfrom rest_framework.serializers import ModelSerializer\nfrom rest_framework.serializers import SerializerMethodField\n\nfrom kolibri.core.auth.models import Classroom\nfrom kolibri.core.exams.models import Exam\nfrom kolibri.core.lessons.models import Lesson\nfrom kolibri.core.logger.models import ContentSummaryLog\nfrom kolibri.core.logger.models import ExamLog\n\n\nclass ExamProgressSerializer(ModelSerializer):\n    \"\"\"\n    Annotates an Exam with progress information based on logs generated\n    by the requesting User\n    \"\"\"\n    class Meta:\n        model = Exam\n        fields = (\n            'active',\n            'id',\n            'progress',\n            'question_count',\n            'title',\n        )\n\n    progress = SerializerMethodField()\n\n    # Mostly copied from UserExamSerializer.to_representation, but working directly\n    # from Exam Model instead of ExamAssignment\n    def get_progress(self, instance):\n        try:\n            examlogs = instance.examlogs.get(user=self.context['user'])\n            return {\n                'score': examlogs.attemptlogs.aggregate(Sum('correct')).get('correct__sum'),\n                'answer_count': examlogs.attemptlogs.count(),\n                'closed': examlogs.closed,\n            }\n        except ExamLog.DoesNotExist:\n            return {\n                'score': None,\n                'answer_count': None,\n                'closed': None,\n            }\n\n\nclass LessonProgressSerializer(ModelSerializer):\n    \"\"\"\n    Annotates a Lesson with progress information based on logs generated\n    by the requesting User\n    \"\"\"\n    progress = SerializerMethodField()\n    resources = JSONField(default='[]')\n\n    class Meta:\n        model = Lesson\n        fields = (\n            'description',\n            'id',\n            'is_active',\n            'title',\n            'progress',\n            'resources',\n        )\n\n    def get_progress(self, instance):\n        content_ids = [resource['content_id'] for resource in instance.resources]\n        resource_progress = ContentSummaryLog.objects \\\n            .filter(\n                user=self.context['user'],\n                content_id__in=content_ids\n            ) \\\n            .aggregate(Sum('progress')).get('progress__sum')\n        return {\n            'resource_progress': resource_progress,\n            'total_resources': len(instance.resources),\n        }\n\n\nclass LearnerClassroomSerializer(ModelSerializer):\n    assignments = SerializerMethodField()\n\n    class Meta:\n        model = Classroom\n        fields = (\n            'id',\n            'name',\n            'assignments',\n        )\n\n    def get_assignments(self, instance):\n        \"\"\"\n        Returns all Exams and Lessons (and progress) assigned to the requesting User\n        \"\"\"\n        current_user = self.context['request'].user\n        memberships = current_user.memberships.all()\n        learner_groups = [m.collection for m in memberships]\n\n        # Return only active Lessons that are assigned to the requesting user's groups\n        # TODO move this to a permission_class on Lesson\n        filtered_lessons = Lesson.objects.filter(\n            lesson_assignments__collection__in=learner_groups,\n            collection=instance,\n            is_active=True,\n        ).distinct()\n\n        filtered_exams = Exam.objects.filter(\n            assignments__collection__in=learner_groups,\n            collection=instance,\n        ).filter(Q(active=True) | Q(examlogs__user=current_user)).distinct()\n\n        return {\n            'lessons': LessonProgressSerializer(\n                filtered_lessons,\n                many=True,\n                context={'user': current_user},\n            ).data,\n            'exams': ExamProgressSerializer(\n                filtered_exams,\n                many=True,\n                context={'user': current_user},\n            ).data,\n        }\n", "path": "kolibri/plugins/learn/serializers.py"}], "after_files": [{"content": "from django.db.models.query import F\nfrom rest_framework.permissions import IsAuthenticated\nfrom rest_framework.viewsets import ReadOnlyModelViewSet\n\nfrom .serializers import LearnerClassroomSerializer\nfrom kolibri.core.auth.api import KolibriAuthPermissionsFilter\nfrom kolibri.core.auth.filters import HierarchyRelationsFilter\nfrom kolibri.core.auth.models import Classroom\nfrom kolibri.core.lessons.models import Lesson\nfrom kolibri.core.lessons.models import LessonAssignment\nfrom kolibri.core.lessons.serializers import LessonSerializer\n\n\nclass LearnerClassroomViewset(ReadOnlyModelViewSet):\n    \"\"\"\n    Returns all Classrooms for which the requesting User is a member,\n    along with all associated assignments.\n    \"\"\"\n    filter_backends = (KolibriAuthPermissionsFilter,)\n    permission_classes = (IsAuthenticated,)\n    serializer_class = LearnerClassroomSerializer\n\n    def get_queryset(self):\n        return HierarchyRelationsFilter(Classroom.objects.all()).filter_by_hierarchy(\n            target_user=self.request.user,\n            ancestor_collection=F('id')\n        )\n\n\nclass LearnerLessonViewset(ReadOnlyModelViewSet):\n    \"\"\"\n    Special Viewset for Learners to view Lessons to which they are assigned.\n    The core Lesson Viewset is locked down to Admin users only.\n    \"\"\"\n    serializer_class = LessonSerializer\n    permission_classes = (IsAuthenticated,)\n\n    def get_queryset(self):\n        assignments = HierarchyRelationsFilter(LessonAssignment.objects.all()) \\\n            .filter_by_hierarchy(\n                target_user=self.request.user,\n                ancestor_collection=F('collection')\n        )\n        return Lesson.objects.filter(\n            lesson_assignments__in=assignments,\n            is_active=True\n        ).distinct()\n", "path": "kolibri/plugins/learn/viewsets.py"}, {"content": "from django.db.models import Q\nfrom django.db.models import Sum\nfrom rest_framework.serializers import JSONField\nfrom rest_framework.serializers import ModelSerializer\nfrom rest_framework.serializers import SerializerMethodField\n\nfrom kolibri.core.auth.filters import HierarchyRelationsFilter\nfrom kolibri.core.auth.models import Classroom\nfrom kolibri.core.exams.models import Exam\nfrom kolibri.core.exams.models import ExamAssignment\nfrom kolibri.core.lessons.models import Lesson\nfrom kolibri.core.lessons.models import LessonAssignment\nfrom kolibri.core.logger.models import ContentSummaryLog\nfrom kolibri.core.logger.models import ExamLog\n\n\nclass ExamProgressSerializer(ModelSerializer):\n    \"\"\"\n    Annotates an Exam with progress information based on logs generated\n    by the requesting User\n    \"\"\"\n    class Meta:\n        model = Exam\n        fields = (\n            'active',\n            'id',\n            'progress',\n            'question_count',\n            'title',\n        )\n\n    progress = SerializerMethodField()\n\n    # Mostly copied from UserExamSerializer.to_representation, but working directly\n    # from Exam Model instead of ExamAssignment\n    def get_progress(self, instance):\n        try:\n            examlogs = instance.examlogs.get(user=self.context['user'])\n            return {\n                'score': examlogs.attemptlogs.aggregate(Sum('correct')).get('correct__sum'),\n                'answer_count': examlogs.attemptlogs.count(),\n                'closed': examlogs.closed,\n            }\n        except ExamLog.DoesNotExist:\n            return {\n                'score': None,\n                'answer_count': None,\n                'closed': None,\n            }\n\n\nclass LessonProgressSerializer(ModelSerializer):\n    \"\"\"\n    Annotates a Lesson with progress information based on logs generated\n    by the requesting User\n    \"\"\"\n    progress = SerializerMethodField()\n    resources = JSONField(default='[]')\n\n    class Meta:\n        model = Lesson\n        fields = (\n            'description',\n            'id',\n            'is_active',\n            'title',\n            'progress',\n            'resources',\n        )\n\n    def get_progress(self, instance):\n        content_ids = [resource['content_id'] for resource in instance.resources]\n        resource_progress = ContentSummaryLog.objects \\\n            .filter(\n                user=self.context['user'],\n                content_id__in=content_ids\n            ) \\\n            .aggregate(Sum('progress')).get('progress__sum')\n        return {\n            'resource_progress': resource_progress,\n            'total_resources': len(instance.resources),\n        }\n\n\nclass LearnerClassroomSerializer(ModelSerializer):\n    assignments = SerializerMethodField()\n\n    class Meta:\n        model = Classroom\n        fields = (\n            'id',\n            'name',\n            'assignments',\n        )\n\n    def get_assignments(self, instance):\n        \"\"\"\n        Returns all Exams and Lessons (and progress) assigned to the requesting User\n        \"\"\"\n        current_user = self.context['request'].user\n\n        # Return only active Lessons that are assigned to the requesting user's groups\n        # TODO move this to a permission_class on Lesson\n        lesson_assignments = HierarchyRelationsFilter(LessonAssignment.objects.all()) \\\n            .filter_by_hierarchy(\n                target_user=current_user,\n                ancestor_collection=instance\n        )\n        filtered_lessons = Lesson.objects.filter(\n            lesson_assignments__in=lesson_assignments,\n            is_active=True\n        ).distinct()\n\n        exam_assignments = HierarchyRelationsFilter(ExamAssignment.objects.all()) \\\n            .filter_by_hierarchy(\n                target_user=current_user,\n                ancestor_collection=instance\n        )\n\n        filtered_exams = Exam.objects.filter(\n            assignments__in=exam_assignments,\n            collection=instance,\n        ).filter(Q(active=True) | Q(examlogs__user=current_user)).distinct()\n\n        return {\n            'lessons': LessonProgressSerializer(\n                filtered_lessons,\n                many=True,\n                context={'user': current_user},\n            ).data,\n            'exams': ExamProgressSerializer(\n                filtered_exams,\n                many=True,\n                context={'user': current_user},\n            ).data,\n        }\n", "path": "kolibri/plugins/learn/serializers.py"}]}