from rest_framework import serializers from apps.course.models import Category, Course, Material, Lesson, Like from .content import ( ImageObjectSerializer, ContentSerializer, ContentCreateSerializer, GallerySerializer, GalleryImageSerializer, ) from apps.content.models import ( Content, Image, Text, ImageText, Video, Gallery, GalleryImage, ImageObject, ) class MaterialCreateSerializer(serializers.ModelSerializer): class Meta: model = Material fields = ( 'id', 'title', 'cover', 'short_description', 'created_at', 'update_at', ) read_only_fields = ( 'id', 'created_at', 'update_at', ) class MaterialSerializer(MaterialCreateSerializer): cover = ImageObjectSerializer(allow_null=True) class LikeSerializer(serializers.ModelSerializer): class Meta: model = Like fields = ( 'id', 'user', 'created_at', 'update_at', ) read_only_fields = ( 'id', 'created_at', 'update_at', ) class CategorySerializer(serializers.ModelSerializer): class Meta: model = Category fields = ( 'id', 'title', ) read_only_fields = ( 'id', ) class CourseCreateSerializer(serializers.ModelSerializer): slug = serializers.SlugField(allow_unicode=True, required=False) content = serializers.ListSerializer( child=ContentCreateSerializer(), required=False, ) materials = MaterialSerializer(many=True, required=False) gallery = GallerySerializer() class Meta: model = Course fields = ( 'id', 'slug', 'author', 'title', 'short_description', 'from_author', 'cover', 'price', 'is_infinite', 'deferred_start_at', 'category', 'duration', 'is_featured', 'url', 'status', 'likes', 'materials', 'created_at', 'update_at', 'content', 'gallery', ) read_only_fields = ( 'id', 'url', 'created_at', 'update_at', ) def dispatch_content(self, course, content, materials): for c in content: if c['type'] == 'text': if 'id' in c['data'] and c['data']['id']: t = Text.objects.get(id=c['data']['id']) t.position = c['data']['position'] t.title = c['data']['title'] t.course = course t.txt = c['data']['txt'] t.save() else: t = Text.objects.create( position=c['data']['position'], title=c['data']['title'], course=course, txt=c['data']['txt'], ) elif c['type'] == 'image': if 'id' in c['data'] and c['data']['id']: i = Image.objects.get(id=c['data']['id']) i.position = c['data']['position'] i.title = c['data']['title'] i.course = course i.img = ImageObject.objects.get(id=c['data']['img']) i.save() else: i = Image.objects.create( position=c['data']['position'], title=c['data']['title'], course=course, img=ImageObject.objects.get(id=c['data']['img']), ) elif c['type'] == 'image-text': if 'id' in c['data'] and c['data']['id']: it = ImageText.objects.get(id=c['data']['id']) it.position = c['data']['position'] it.title = c['data']['title'] it.course = course it.img = ImageObject.objects.get(id=c['data']['img']) it.txt = c['data']['txt'] it.save() else: it = ImageText.objects.create( position=c['data']['position'], title=c['data']['title'], course=course, img=ImageObject.objects.get(id=c['data']['img']), txt=c['data']['txt'], ) elif c['type'] == 'video': if 'id' in c['data'] and c['data']['id']: v = Video.objects.get(id=c['data']['id']) v.position = c['data']['position'] v.title = c['data']['title'] v.course = course v.url = c['data']['url'] v.save() else: v = Video.objects.create( position=c['data']['position'], title=c['data']['title'], course=course, url=c['data']['url'], ) for material in materials: if 'id' in material and material['id']: m = Material.objects.get(id=material['id']) m.title = material['title'] m.cover = ImageObject.objects.get(id=material['cover']) m.short_description = material['short_description'] m.save() else: m = Material.objects.create( title=material['title'], cover=ImageObject.objects.get(id=material['cover']), short_description=material['short_description'], ) course.materials.add(m) def dispatch_gallery(self, course, gallery): if gallery: if 'id' in gallery and gallery['id']: g = Gallery.objects.get(id=gallery['id']) g.title = gallery.get('title', g.title) g.save() else: g = Gallery.objects.create( title=gallery.get('title', '') ) if 'images' in gallery: for i in gallery['images']: if 'id' in i and i['id']: gi = GalleryImage.objects.get(id=i['id']) gi.gallery = g gi.img = i['img'] gi.save() else: gi = GalleryImage.objects.create( gallery=g, img=i['img'], ) course.gallery = g course.save() def create(self, validated_data): content = validated_data.pop('content', []) materials = validated_data.pop('materials', []) gallery = validated_data.pop('gallery', {}) course = super().create(validated_data) self.dispatch_content(course, content, materials) self.dispatch_gallery(course, gallery) return course def update(self, instance, validated_data): content = validated_data.pop('content', []) materials = validated_data.pop('materials', []) gallery = validated_data.pop('gallery', {}) course = super().update(instance, validated_data) self.dispatch_content(course, content, materials) self.dispatch_gallery(course, gallery) return course class CourseSerializer(CourseCreateSerializer): category = CategorySerializer() materials = MaterialSerializer(many=True) cover = ImageObjectSerializer() gallery = GallerySerializer() content = ContentSerializer(many=True) class LessonCreateSerializer(serializers.ModelSerializer): content = serializers.ListSerializer( child=ContentCreateSerializer(), required=False, ) class Meta: model = Lesson fields = ( 'id', 'title', 'short_description', 'course', 'cover', 'content', 'created_at', 'update_at', ) read_only_fields = ( 'id', 'created_at', 'update_at', ) def dispatch_content(self, lesson, validated_data, content): for c in content: if c['type'] == 'text': if 'id' in c['data'] and c['data']['id']: t = Text.objects.get(id=c['data']['id']) t.position = c['data']['position'] t.title = c['data']['title'] t.lesson = lesson t.txt = c['data']['txt'] t.save() else: t = Text.objects.create( position=c['data']['position'], title=c['data']['title'], lesson=lesson, txt=c['data']['txt'], ) elif c['type'] == 'image': if 'id' in c['data'] and c['data']['id']: i = Image.objects.get(id=c['data']['id']) i.position = c['data']['position'] i.title = c['data']['title'] i.lesson = lesson i.img = ImageObject.objects.get(id=c['data']['img']) i.save() else: i = Image.objects.create( position=c['data']['position'], title=c['data']['title'], lesson=lesson, img=ImageObject.objects.get(id=c['data']['img']), ) elif c['type'] == 'image-text': if 'id' in c['data'] and c['data']['id']: it = ImageText.objects.get(id=c['data']['id']) it.position = c['data']['position'] it.title = c['data']['title'] it.lesson = lesson it.img = ImageObject.objects.get(id=c['data']['img']) it.txt = c['data']['txt'] it.save() else: it = ImageText.objects.create( position=c['data']['position'], title=c['data']['title'], lesson=lesson, img=ImageObject.objects.get(id=c['data']['img']), txt=c['data']['txt'], ) elif c['type'] == 'video': if 'id' in c['data'] and c['data']['id']: v = Video.objects.get(id=c['data']['id']) v.position = c['data']['position'] v.title = c['data']['title'] v.lesson = lesson v.url = c['data']['url'] v.save() else: v = Video.objects.create( position=c['data']['position'], title=c['data']['title'], lesson=lesson, url=c['data']['url'], ) def create(self, validated_data): content = validated_data.pop('content', []) lesson = super().create(validated_data) self.dispatch_content(lesson, validated_data, content) return lesson def update(self, instance, validated_data): content = validated_data.pop('content', []) lesson = super().update(instance, validated_data) self.dispatch_content(lesson, validated_data, content) return lesson class LessonSerializer(LessonCreateSerializer): course = CourseSerializer() cover = ImageObjectSerializer() content = ContentSerializer()