from rest_framework import serializers from apps.course.models import ( Category, Course, Comment, CourseComment, LessonComment, Material, Lesson, Like, ) from .content import ( ImageObjectSerializer, ContentSerializer, ContentCreateSerializer, GallerySerializer, GalleryImageSerializer, ) from apps.content.models import ( Content, Image, Text, ImageText, Video, Gallery, GalleryImage, ImageObject, ) from .user import UserSerializer from .mixins import DispatchContentMixin, DispatchGalleryMixin, DispatchMaterialMixin 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 CourseBulkChangeCategorySerializer(serializers.Serializer): old_category = serializers.IntegerField() new_category = serializers.IntegerField() class CourseCreateSerializer(DispatchContentMixin, DispatchGalleryMixin, DispatchMaterialMixin, serializers.ModelSerializer ): title = serializers.CharField(allow_blank=True) short_description = serializers.CharField(allow_blank=True) slug = serializers.SlugField(allow_unicode=True, allow_blank=True, allow_null=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', 'deactivated_at', 'content', 'gallery', 'lessons', ) read_only_fields = ( 'id', 'url', 'lessons', 'created_at', 'update_at', 'deactivated_at', ) def create(self, validated_data): content = validated_data.pop('content', []) materials = validated_data.pop('materials', []) gallery = validated_data.pop('gallery', {}) author = validated_data.get('author', None) if not author: validated_data['author'] = self.context['request'].user course = super().create(validated_data) self.dispatch_content(course, content) self.dispatch_materials(course, 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', {}) author = validated_data.get('author', None) if not instance.author or author and instance.author != author: validated_data['author'] = self.context['request'].user course = super().update(instance, validated_data) self.dispatch_materials(course, materials) self.dispatch_content(course, content) self.dispatch_gallery(course, gallery) return course def to_representation(self, instance): return CourseSerializer(instance=instance, context=self.context).to_representation(instance) 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', 'deactivated_at', ) read_only_fields = ( 'id', 'created_at', 'update_at', 'deactivated_at', ) def dispatch_content(self, lesson, content): for c in content: if 'type' not in c or not c['type'] or 'data' not in c or not c['data']: continue ctype = c['type'] cdata = c['data'] if ctype == 'text': if 'id' in cdata and cdata['id']: t = Text.objects.get(id=cdata['id']) t.position = cdata['position'] t.title = cdata['title'] t.lesson = lesson t.txt = cdata['txt'] t.save() else: t = Text.objects.create( position=cdata['position'], title=cdata['title'], lesson=lesson, txt=cdata['txt'], ) elif ctype == 'image': if 'id' in cdata and cdata['id']: image = Image.objects.get(id=cdata['id']) image.position = cdata['position'] image.title = cdata['title'] image.lesson = lesson image.img = ImageObject.objects.get(id=cdata['img']) image.save() else: image = Image.objects.create( position=cdata['position'], title=cdata['title'], lesson=lesson, img=ImageObject.objects.get(id=cdata['img']), ) elif ctype == 'image-text': if 'id' in cdata and cdata['id']: it = ImageText.objects.get(id=cdata['id']) it.position = cdata['position'] it.title = cdata['title'] it.lesson = lesson it.img = ImageObject.objects.get(id=cdata['img']) it.txt = cdata['txt'] it.save() else: it = ImageText.objects.create( position=cdata['position'], title=cdata['title'], lesson=lesson, img=ImageObject.objects.get(id=cdata['img']), txt=cdata['txt'], ) elif ctype == 'video': if 'id' in cdata and cdata['id']: v = Video.objects.get(id=cdata['id']) v.position = cdata['position'] v.title = cdata['title'] v.lesson = lesson v.url = cdata['url'] v.save() else: v = Video.objects.create( position=cdata['position'], title=cdata['title'], lesson=lesson, url=cdata['url'], ) elif ctype == 'images': if 'id' in cdata and cdata['id']: g = Gallery.objects.get(id=cdata['id']) g.position = cdata['position'] g.title = cdata['title'] g.lesson = lesson g.save() if 'images' in cdata: for image in cdata['images']: gi = GalleryImage.objects.create( gallery=g, img=ImageObject.objects.get(id=image['img']), ) else: g = Gallery.objects.create( lesson=lesson, position=cdata['position'], title=cdata['title'], ) if 'images' in cdata: for image in cdata['images']: gi = GalleryImage.objects.create( gallery=g, img=ImageObject.objects.get(id=image['img']), ) def create(self, validated_data): content = validated_data.pop('content', []) lesson = super().create(validated_data) self.dispatch_content(lesson, content) return lesson def update(self, instance, validated_data): content = validated_data.pop('content', []) lesson = super().update(instance, validated_data) self.dispatch_content(lesson, content) return lesson def to_representation(self, instance): return LessonSerializer(instance, context=self.context).to_representation(instance) class LessonSerializer(serializers.ModelSerializer): # course = CourseSerializer() cover = ImageObjectSerializer() content = ContentSerializer(many=True) class Meta: model = Lesson fields = ( 'id', 'title', 'short_description', 'course', 'cover', 'content', 'created_at', 'update_at', 'deactivated_at', ) read_only_fields = ( 'id', 'created_at', 'update_at', 'deactivated_at', ) class CourseSerializer(serializers.ModelSerializer): author = UserSerializer() category = CategorySerializer() materials = MaterialSerializer(many=True) cover = ImageObjectSerializer() gallery = GallerySerializer() content = ContentSerializer(many=True) lessons = LessonSerializer(many=True) 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', 'deactivated_at', 'content', 'gallery', 'lessons', ) read_only_fields = ( 'id', 'url', 'lessons', 'created_at', 'update_at', 'deactivated_at', ) class CommentSerializer(serializers.ModelSerializer): author = UserSerializer() class Meta: model = Comment fields = ( 'id', 'content', 'author', 'parent', 'deactivated_at', 'created_at', 'update_at', ) read_only_fields = ( 'id', 'deactivated_at', 'created_at', 'update_at', ) def to_representation(self, instance): if isinstance(instance, CourseComment): return CourseCommentSerializer(instance, context=self.context).to_representation(instance) elif isinstance(instance, LessonComment): return LessonCommentSerializer(instance, context=self.context).to_representation(instance) class CourseCommentSerializer(serializers.ModelSerializer): author = UserSerializer() children = CommentSerializer(many=True) class Meta: model = CourseComment fields = CommentSerializer.Meta.fields + ( 'course', 'children', ) read_only_fields = CommentSerializer.Meta.read_only_fields + ( 'children', ) class LessonCommentSerializer(serializers.ModelSerializer): author = UserSerializer() children = CommentSerializer(many=True) class Meta: model = LessonComment fields = CommentSerializer.Meta.fields + ( 'lesson', 'children', ) read_only_fields = CommentSerializer.Meta.read_only_fields + ( 'children', )