|
|
@ -138,15 +138,16 @@ class AdminCourseLessonSerializer(serializers.Serializer): |
|
|
id = serializers.IntegerField(read_only=True) |
|
|
id = serializers.IntegerField(read_only=True) |
|
|
course = serializers.IntegerField(required=False, read_only=True) |
|
|
course = serializers.IntegerField(required=False, read_only=True) |
|
|
chapter = serializers.IntegerField() |
|
|
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) |
|
|
title = serializers.CharField(max_length=255, required=False, allow_blank=True, allow_null=True) |
|
|
priority = serializers.IntegerField(required=False, allow_null=True) |
|
|
priority = serializers.IntegerField(required=False, allow_null=True) |
|
|
is_active = serializers.BooleanField(default=True) |
|
|
is_active = serializers.BooleanField(default=True) |
|
|
|
|
|
|
|
|
# Lesson (Base Content) fields |
|
|
# 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) |
|
|
content_file = FileFieldSerializer(required=False, allow_null=True) |
|
|
video_link = serializers.CharField(max_length=500, required=False, allow_blank=True, 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): |
|
|
def to_representation(self, instance): |
|
|
""" |
|
|
""" |
|
|
@ -157,6 +158,7 @@ class AdminCourseLessonSerializer(serializers.Serializer): |
|
|
'id': instance.id, |
|
|
'id': instance.id, |
|
|
'course': instance.course_id, |
|
|
'course': instance.course_id, |
|
|
'chapter': instance.chapter_id, |
|
|
'chapter': instance.chapter_id, |
|
|
|
|
|
'lesson': instance.lesson_id, |
|
|
'title': instance.title or (lesson_obj.title if lesson_obj else ""), |
|
|
'title': instance.title or (lesson_obj.title if lesson_obj else ""), |
|
|
'priority': instance.priority, |
|
|
'priority': instance.priority, |
|
|
'is_active': instance.is_active, |
|
|
'is_active': instance.is_active, |
|
|
@ -175,19 +177,32 @@ class AdminCourseLessonSerializer(serializers.Serializer): |
|
|
priority = validated_data.get('priority') |
|
|
priority = validated_data.get('priority') |
|
|
is_active = validated_data.get('is_active', True) |
|
|
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 |
|
|
# 2. Create CourseLesson junction |
|
|
course_lesson = CourseLesson.objects.create( |
|
|
course_lesson = CourseLesson.objects.create( |
|
|
@ -237,8 +252,9 @@ class AdminCourseLessonSerializer(serializers.Serializer): |
|
|
class AdminCourseAttachmentSerializer(serializers.Serializer): |
|
|
class AdminCourseAttachmentSerializer(serializers.Serializer): |
|
|
id = serializers.IntegerField(read_only=True) |
|
|
id = serializers.IntegerField(read_only=True) |
|
|
course = serializers.IntegerField() |
|
|
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) |
|
|
file_size = serializers.IntegerField(read_only=True) |
|
|
|
|
|
|
|
|
def to_representation(self, instance): |
|
|
def to_representation(self, instance): |
|
|
@ -246,6 +262,7 @@ class AdminCourseAttachmentSerializer(serializers.Serializer): |
|
|
return { |
|
|
return { |
|
|
'id': instance.id, |
|
|
'id': instance.id, |
|
|
'course': instance.course_id, |
|
|
'course': instance.course_id, |
|
|
|
|
|
'attachment': instance.attachment_id, |
|
|
'title': attachment_obj.title if attachment_obj else "", |
|
|
'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': 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 |
|
|
'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_id = validated_data.pop('course') |
|
|
course = Course.objects.get(pk=course_id) |
|
|
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 |
|
|
# 2. Link to Course |
|
|
course_attachment = CourseAttachment.objects.create( |
|
|
course_attachment = CourseAttachment.objects.create( |
|
|
@ -289,14 +319,16 @@ class AdminCourseAttachmentSerializer(serializers.Serializer): |
|
|
class AdminCourseGlossarySerializer(serializers.Serializer): |
|
|
class AdminCourseGlossarySerializer(serializers.Serializer): |
|
|
id = serializers.IntegerField(read_only=True) |
|
|
id = serializers.IntegerField(read_only=True) |
|
|
course = serializers.IntegerField() |
|
|
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): |
|
|
def to_representation(self, instance): |
|
|
glossary_obj = instance.glossary |
|
|
glossary_obj = instance.glossary |
|
|
return { |
|
|
return { |
|
|
'id': instance.id, |
|
|
'id': instance.id, |
|
|
'course': instance.course_id, |
|
|
'course': instance.course_id, |
|
|
|
|
|
'glossary': instance.glossary_id, |
|
|
'title': glossary_obj.title if glossary_obj else "", |
|
|
'title': glossary_obj.title if glossary_obj else "", |
|
|
'description': glossary_obj.description 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_id = validated_data.pop('course') |
|
|
course = Course.objects.get(pk=course_id) |
|
|
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 |
|
|
# 2. Link to Course |
|
|
course_glossary = CourseGlossary.objects.create( |
|
|
course_glossary = CourseGlossary.objects.create( |
|
|
|