You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
438 lines
12 KiB
438 lines
12 KiB
from django.contrib.auth import get_user_model
|
|
from ipware import get_client_ip
|
|
from rest_framework import serializers
|
|
from rest_framework.validators import UniqueValidator
|
|
from drf_dynamic_fields import DynamicFieldsMixin
|
|
|
|
from apps.course.models import (
|
|
Category, Course,
|
|
Comment, CourseComment, LessonComment,
|
|
Material, Lesson,
|
|
Like,
|
|
LiveLessonComment)
|
|
from .content import (
|
|
ImageObjectSerializer, ContentSerializer, ContentCreateSerializer,
|
|
GallerySerializer, )
|
|
from .mixins import DispatchContentMixin, DispatchGalleryMixin, DispatchMaterialMixin
|
|
from .user import UserSerializer
|
|
|
|
User = get_user_model()
|
|
|
|
|
|
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 LikeCreateSerializer(serializers.ModelSerializer):
|
|
|
|
class Meta:
|
|
model = Like
|
|
fields = ['user']
|
|
|
|
def create(self, validated_data):
|
|
# FIXME
|
|
if validated_data.get('user'):
|
|
user = validated_data.get('user')
|
|
else:
|
|
user = self.context['request'].user
|
|
client_ip, is_routable = get_client_ip(self.context['request'])
|
|
like = Like.objects.create(user=user, ip=client_ip)
|
|
return like
|
|
|
|
def to_representation(self, instance):
|
|
return LikeSerializer(instance, context=self.context).to_representation(instance)
|
|
|
|
|
|
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, validators=[UniqueValidator(queryset=Course.objects.all())])
|
|
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',
|
|
'old_price',
|
|
'age',
|
|
'is_infinite',
|
|
'deferred_start_at',
|
|
'category',
|
|
'access_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(DispatchContentMixin, 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',
|
|
'position',
|
|
)
|
|
|
|
read_only_fields = (
|
|
'id',
|
|
'created_at',
|
|
'update_at',
|
|
'deactivated_at',
|
|
)
|
|
|
|
def create(self, validated_data):
|
|
content = validated_data.pop('content', [])
|
|
lesson = super().create(validated_data)
|
|
if not validated_data.get('position'):
|
|
lesson.set_last_position()
|
|
lesson.save()
|
|
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',
|
|
'position',
|
|
)
|
|
|
|
read_only_fields = (
|
|
'id',
|
|
'created_at',
|
|
'update_at',
|
|
'deactivated_at',
|
|
)
|
|
|
|
|
|
class CourseSerializer(DynamicFieldsMixin, 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',
|
|
'old_price',
|
|
'age',
|
|
'is_infinite',
|
|
'deferred_start_at',
|
|
'category',
|
|
'access_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',
|
|
'created_at_humanize',
|
|
'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)
|
|
elif isinstance(instance, LiveLessonComment):
|
|
return LiveLessonCommentSerializer(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',
|
|
)
|
|
|
|
|
|
class LiveLessonCommentSerializer(serializers.ModelSerializer):
|
|
author = UserSerializer()
|
|
children = CommentSerializer(many=True)
|
|
|
|
class Meta:
|
|
model = LiveLessonComment
|
|
fields = CommentSerializer.Meta.fields + (
|
|
'live_lesson',
|
|
'children',
|
|
)
|
|
|
|
read_only_fields = CommentSerializer.Meta.read_only_fields + (
|
|
'children',
|
|
)
|
|
|
|
|
|
|
|
class CommentCreateSerializer(serializers.ModelSerializer):
|
|
obj_type = serializers.CharField(required=True)
|
|
obj_id = serializers.IntegerField(required=True)
|
|
|
|
class Meta:
|
|
model = Comment
|
|
fields = (
|
|
'id',
|
|
'content',
|
|
'author',
|
|
'parent',
|
|
'deactivated_at',
|
|
'created_at',
|
|
'update_at',
|
|
'obj_type',
|
|
'obj_id',
|
|
)
|
|
|
|
read_only_fields = (
|
|
'id',
|
|
'deactivated_at',
|
|
'created_at',
|
|
'update_at',
|
|
)
|
|
|
|
def create(self, validated_data):
|
|
obj_type = validated_data.pop('obj_type', None)
|
|
obj_id = validated_data.pop('obj_id', None)
|
|
if obj_type == Comment.OBJ_TYPE_COURSE:
|
|
validated_data['course_id'] = obj_id
|
|
return CourseCommentSerializer().create(validated_data)
|
|
elif obj_type == Comment.OBJ_TYPE_LESSON:
|
|
validated_data['lesson_id'] = obj_id
|
|
return LessonCommentSerializer().create(validated_data)
|
|
elif obj_type == Comment.OBJ_TYPE_LIVE_LESSON:
|
|
validated_data['live_lesson_id'] = obj_id
|
|
return LiveLessonCommentSerializer().create(validated_data)
|
|
|
|
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)
|
|
elif isinstance(instance, LiveLessonComment):
|
|
return LiveLessonCommentSerializer(instance, context=self.context).to_representation(instance)
|
|
|