From 6d9d18b1407d1ee38e738c73531e5c64274017b9 Mon Sep 17 00:00:00 2001 From: Toksi Date: Tue, 10 Mar 2026 12:14:53 +0500 Subject: [PATCH] =?UTF-8?q?=D0=94=D0=BE=D0=B1=D0=B0=D0=B2=D0=BB=D0=B5?= =?UTF-8?q?=D0=BD=D1=8B=20task=5Fcount=20=D0=B4=D0=BB=D1=8F=20=D1=83=D1=80?= =?UTF-8?q?=D0=BE=D0=BA=D0=BE=D0=B2=20=D0=B8=20avatar=5Furl=20=D0=B4=D0=BB?= =?UTF-8?q?=D1=8F=20=D0=BC=D0=BE=D0=B4=D1=83=D0=BB=D0=B5=D0=B9=20=D0=B2=20?= =?UTF-8?q?=D1=81=D1=82=D1=80=D1=83=D0=BA=D1=82=D1=83=D1=80=D0=B5=20=D0=BA?= =?UTF-8?q?=D1=83=D1=80=D1=81=D0=B0,=20=D0=BE=D0=BF=D1=82=D0=B8=D0=BC?= =?UTF-8?q?=D0=B8=D0=B7=D0=B8=D1=80=D0=BE=D0=B2=D0=B0=D0=BD=D0=B0=20=D0=B7?= =?UTF-8?q?=D0=B0=D0=B3=D1=80=D1=83=D0=B7=D0=BA=D0=B0=20=D1=81=D0=B2=D1=8F?= =?UTF-8?q?=D0=B7=D0=B0=D0=BD=D0=BD=D1=8B=D1=85=20=D0=B4=D0=B0=D0=BD=D0=BD?= =?UTF-8?q?=D1=8B=D1=85=20=D0=B4=D0=BB=D1=8F=20API=20=D0=BA=D1=83=D1=80?= =?UTF-8?q?=D1=81=D0=BE=D0=B2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- courses/serializers.py | 2 ++ courses/services/querysets.py | 12 ++++++++++-- courses/views.py | 3 +++ 3 files changed, 15 insertions(+), 2 deletions(-) diff --git a/courses/serializers.py b/courses/serializers.py index 13eea2de..709df8fe 100644 --- a/courses/serializers.py +++ b/courses/serializers.py @@ -102,6 +102,7 @@ class CourseLessonStructureSerializer(serializers.Serializer): module_id = serializers.IntegerField() title = serializers.CharField() order = serializers.IntegerField(min_value=1) + task_count = serializers.IntegerField(min_value=0) status = serializers.ChoiceField(choices=CourseLessonContentStatus.choices) is_available = serializers.BooleanField() progress_status = serializers.ChoiceField(choices=ProgressStatus.choices) @@ -115,6 +116,7 @@ class CourseModuleStructureSerializer(serializers.Serializer): course_id = serializers.IntegerField() title = serializers.CharField() order = serializers.IntegerField(min_value=1) + avatar_url = serializers.URLField(allow_null=True) start_date = serializers.DateField() status = serializers.ChoiceField(choices=CourseModuleContentStatus.choices) is_available = serializers.BooleanField() diff --git a/courses/services/querysets.py b/courses/services/querysets.py index 8f3dc051..156f9b1e 100644 --- a/courses/services/querysets.py +++ b/courses/services/querysets.py @@ -1,10 +1,11 @@ -from django.db.models import Prefetch +from django.db.models import Count, Prefetch, Q from courses.models import ( Course, CourseContentStatus, CourseLesson, CourseLessonContentStatus, + CourseTaskContentStatus, ) @@ -17,5 +18,12 @@ def published_lessons_prefetch(): "lessons", queryset=CourseLesson.objects.filter( status=CourseLessonContentStatus.PUBLISHED - ).order_by("order", "id"), + ) + .annotate( + task_count=Count( + "tasks", + filter=Q(tasks__status=CourseTaskContentStatus.PUBLISHED), + ) + ) + .order_by("order", "id"), ) diff --git a/courses/views.py b/courses/views.py index bcceddf6..28c50c43 100644 --- a/courses/views.py +++ b/courses/views.py @@ -156,6 +156,7 @@ def get(self, request, pk: int): queryset=CourseModule.objects.filter( status=CourseModuleContentStatus.PUBLISHED ) + .select_related("avatar_file") .order_by("order", "id") .prefetch_related(published_lessons_prefetch()), ), @@ -222,6 +223,7 @@ def get(self, request, pk: int): "module_id": module.id, "title": lesson.title, "order": lesson.order, + "task_count": lesson.task_count, "status": lesson.status, "is_available": lesson_available, "progress_status": lesson_status, @@ -239,6 +241,7 @@ def get(self, request, pk: int): "course_id": course.id, "title": module.title, "order": module.order, + "avatar_url": module.avatar_file_id, "start_date": module.start_date, "status": module.status, "is_available": module_available,