From 7ee05a6657eb8a189f3b8452c0ec0d40a6ddb9ee Mon Sep 17 00:00:00 2001 From: mohsentaba Date: Tue, 26 May 2026 18:35:11 +0330 Subject: [PATCH] fixed course serializers --- apps/course/serializers/admin.py | 115 +++++++++++++++++++++---------- 1 file changed, 80 insertions(+), 35 deletions(-) diff --git a/apps/course/serializers/admin.py b/apps/course/serializers/admin.py index 0352452..70e2acb 100644 --- a/apps/course/serializers/admin.py +++ b/apps/course/serializers/admin.py @@ -138,15 +138,16 @@ class AdminCourseLessonSerializer(serializers.Serializer): id = serializers.IntegerField(read_only=True) course = serializers.IntegerField(required=False, read_only=True) chapter = serializers.IntegerField() + lesson = serializers.IntegerField(required=False, write_only=True, allow_null=True) title = serializers.CharField(max_length=255, required=False, allow_blank=True, allow_null=True) priority = serializers.IntegerField(required=False, allow_null=True) is_active = serializers.BooleanField(default=True) # Lesson (Base Content) fields - content_type = serializers.ChoiceField(choices=Lesson.ContentTypeChoices.choices) + content_type = serializers.ChoiceField(choices=Lesson.ContentTypeChoices.choices, required=False, allow_null=True) content_file = FileFieldSerializer(required=False, allow_null=True) video_link = serializers.CharField(max_length=500, required=False, allow_blank=True, allow_null=True) - duration = serializers.IntegerField(min_value=0) + duration = serializers.IntegerField(min_value=0, required=False, default=0) def to_representation(self, instance): """ @@ -157,6 +158,7 @@ class AdminCourseLessonSerializer(serializers.Serializer): 'id': instance.id, 'course': instance.course_id, 'chapter': instance.chapter_id, + 'lesson': instance.lesson_id, 'title': instance.title or (lesson_obj.title if lesson_obj else ""), 'priority': instance.priority, 'is_active': instance.is_active, @@ -175,19 +177,32 @@ class AdminCourseLessonSerializer(serializers.Serializer): priority = validated_data.get('priority') is_active = validated_data.get('is_active', True) - content_type = validated_data.get('content_type') - content_file = validated_data.get('content_file') - video_link = validated_data.get('video_link') - duration = validated_data.get('duration', 0) - - # 1. Create Lesson Base - lesson = Lesson.objects.create( - title=title or "Base Lesson", - content_type=content_type, - content_file=content_file, - video_link=video_link, - duration=duration - ) + lesson_id = validated_data.get('lesson') + if lesson_id: + try: + lesson = Lesson.objects.get(pk=lesson_id) + except Lesson.DoesNotExist: + raise serializers.ValidationError({"lesson": "Lesson does not exist."}) + + # Check if already linked to this course + if CourseLesson.objects.filter(course=course, lesson=lesson).exists(): + raise serializers.ValidationError({"detail": "This lesson is already linked to this course."}) + else: + content_type = validated_data.get('content_type') + if not content_type: + raise serializers.ValidationError({"detail": "Content type is required for new lessons."}) + content_file = validated_data.get('content_file') + video_link = validated_data.get('video_link') + duration = validated_data.get('duration', 0) + + # 1. Create Lesson Base + lesson = Lesson.objects.create( + title=title or "Base Lesson", + content_type=content_type, + content_file=content_file, + video_link=video_link, + duration=duration + ) # 2. Create CourseLesson junction course_lesson = CourseLesson.objects.create( @@ -237,8 +252,9 @@ class AdminCourseLessonSerializer(serializers.Serializer): class AdminCourseAttachmentSerializer(serializers.Serializer): id = serializers.IntegerField(read_only=True) course = serializers.IntegerField() - title = serializers.CharField(max_length=255) - file = FileFieldSerializer(required=True) + attachment = serializers.IntegerField(required=False, write_only=True, allow_null=True) + title = serializers.CharField(max_length=255, required=False, allow_blank=True, allow_null=True) + file = FileFieldSerializer(required=False, allow_null=True) file_size = serializers.IntegerField(read_only=True) def to_representation(self, instance): @@ -246,6 +262,7 @@ class AdminCourseAttachmentSerializer(serializers.Serializer): return { 'id': instance.id, 'course': instance.course_id, + 'attachment': instance.attachment_id, 'title': attachment_obj.title if attachment_obj else "", 'file': serialize_file(attachment_obj.file, self) if attachment_obj and attachment_obj.file else None, 'file_size': attachment_obj.file_size if attachment_obj else 0 @@ -255,14 +272,27 @@ class AdminCourseAttachmentSerializer(serializers.Serializer): course_id = validated_data.pop('course') course = Course.objects.get(pk=course_id) - title = validated_data.get('title') - file_data = validated_data.get('file') - - # 1. Create Base Attachment - attachment = Attachment.objects.create( - title=title, - file=file_data - ) + attachment_id = validated_data.get('attachment') + if attachment_id: + try: + attachment = Attachment.objects.get(pk=attachment_id) + except Attachment.DoesNotExist: + raise serializers.ValidationError({"attachment": "Attachment does not exist."}) + + # Check if already linked + if CourseAttachment.objects.filter(course=course, attachment=attachment).exists(): + raise serializers.ValidationError({"detail": "This attachment is already linked to this course."}) + else: + title = validated_data.get('title') + file_data = validated_data.get('file') + if not title or not file_data: + raise serializers.ValidationError({"detail": "Title and file are required for new attachments."}) + + # 1. Create Base Attachment + attachment = Attachment.objects.create( + title=title, + file=file_data + ) # 2. Link to Course course_attachment = CourseAttachment.objects.create( @@ -289,14 +319,16 @@ class AdminCourseAttachmentSerializer(serializers.Serializer): class AdminCourseGlossarySerializer(serializers.Serializer): id = serializers.IntegerField(read_only=True) course = serializers.IntegerField() - title = serializers.CharField(max_length=555) - description = serializers.CharField() + glossary = serializers.IntegerField(required=False, write_only=True, allow_null=True) + title = serializers.CharField(max_length=555, required=False, allow_blank=True, allow_null=True) + description = serializers.CharField(required=False, allow_blank=True, allow_null=True) def to_representation(self, instance): glossary_obj = instance.glossary return { 'id': instance.id, 'course': instance.course_id, + 'glossary': instance.glossary_id, 'title': glossary_obj.title if glossary_obj else "", 'description': glossary_obj.description if glossary_obj else "" } @@ -305,14 +337,27 @@ class AdminCourseGlossarySerializer(serializers.Serializer): course_id = validated_data.pop('course') course = Course.objects.get(pk=course_id) - title = validated_data.get('title') - description = validated_data.get('description') - - # 1. Create Base Glossary - glossary = Glossary.objects.create( - title=title, - description=description - ) + glossary_id = validated_data.get('glossary') + if glossary_id: + try: + glossary = Glossary.objects.get(pk=glossary_id) + except Glossary.DoesNotExist: + raise serializers.ValidationError({"glossary": "Glossary term does not exist."}) + + # Check if already linked + if CourseGlossary.objects.filter(course=course, glossary=glossary).exists(): + raise serializers.ValidationError({"detail": "This glossary term is already linked to this course."}) + else: + title = validated_data.get('title') + description = validated_data.get('description') + if not title or not description: + raise serializers.ValidationError({"detail": "Title and description are required for new glossary terms."}) + + # 1. Create Base Glossary + glossary = Glossary.objects.create( + title=title, + description=description + ) # 2. Link to Course course_glossary = CourseGlossary.objects.create(