""" Сериализаторы для интерактивной доски. """ from rest_framework import serializers from .models import Board, BoardElement, BoardSnapshot from apps.users.serializers import UserSerializer class BoardElementSerializer(serializers.ModelSerializer): """Сериализатор элемента доски.""" created_by = UserSerializer(read_only=True) locked_by = UserSerializer(read_only=True) class Meta: model = BoardElement fields = [ 'id', 'board', 'element_type', 'x', 'y', 'width', 'height', 'rotation', 'z_index', 'content', 'font_size', 'font_family', 'font_weight', 'text_align', 'text_color', 'shape_type', 'fill_color', 'stroke_color', 'stroke_width', 'opacity', 'image_url', 'drawing_data', 'arrow_start_element', 'arrow_end_element', 'created_by', 'locked', 'locked_by', 'is_deleted', 'created_at', 'updated_at' ] read_only_fields = [ 'created_by', 'locked_by', 'is_deleted', 'created_at', 'updated_at' ] class BoardElementCreateSerializer(serializers.ModelSerializer): """Сериализатор создания элемента доски.""" board_id = serializers.UUIDField(write_only=True) class Meta: model = BoardElement fields = [ 'board_id', 'element_type', 'x', 'y', 'width', 'height', 'rotation', 'z_index', 'content', 'font_size', 'font_family', 'font_weight', 'text_align', 'text_color', 'shape_type', 'fill_color', 'stroke_color', 'stroke_width', 'opacity', 'image_url', 'drawing_data', ] def validate_board_id(self, value): """Проверка доски.""" try: board = Board.objects.get(board_id=value) except Board.DoesNotExist: raise serializers.ValidationError('Доска не найдена') # Проверяем доступ user = self.context['request'].user if not board.has_access(user): raise serializers.ValidationError('У вас нет доступа к этой доске') return value def create(self, validated_data): """Создание элемента.""" board_id = validated_data.pop('board_id') board = Board.objects.get(board_id=board_id) user = self.context['request'].user element = BoardElement.objects.create( board=board, created_by=user, **validated_data ) # Обновляем счетчик элементов board.update_elements_count() # Отмечаем редактирование board.mark_edited(user) return element class BoardSerializer(serializers.ModelSerializer): """Сериализатор доски.""" owner = UserSerializer(read_only=True) mentor = UserSerializer(read_only=True) student = UserSerializer(read_only=True) participants = UserSerializer(many=True, read_only=True) last_edited_by = UserSerializer(read_only=True) elements = BoardElementSerializer(many=True, read_only=True) files_count = serializers.SerializerMethodField() snapshot_elements_count = serializers.SerializerMethodField() class Meta: model = Board fields = [ 'id', 'board_id', 'title', 'description', 'owner', 'mentor', 'student', 'access_type', 'participants', 'background_color', 'grid_enabled', 'width', 'height', 'is_active', 'is_template', 'views_count', 'elements_count', 'files_count', 'snapshot_elements_count', 'last_edited_by', 'last_edited_at', 'elements', 'created_at', 'updated_at' ] read_only_fields = [ 'board_id', 'owner', 'mentor', 'student', 'views_count', 'elements_count', 'last_edited_by', 'last_edited_at', 'created_at', 'updated_at' ] def get_files_count(self, obj): """Получить количество файлов изображений из snapshot.""" return obj.get_files_count() def get_snapshot_elements_count(self, obj): """Получить количество элементов из snapshot.""" return obj.get_elements_count_from_snapshot() class BoardListSerializer(serializers.ModelSerializer): """Сериализатор списка досок (упрощенный).""" owner = UserSerializer(read_only=True) mentor = UserSerializer(read_only=True) student = UserSerializer(read_only=True) last_edited_by = UserSerializer(read_only=True) class Meta: model = Board fields = [ 'id', 'board_id', 'title', 'description', 'owner', 'mentor', 'student', 'access_type', 'background_color', 'is_active', 'is_template', 'views_count', 'elements_count', 'last_edited_by', 'last_edited_at', 'created_at' ] class BoardCreateSerializer(serializers.ModelSerializer): """Сериализатор создания доски.""" # mentor и student обязательны для доски типа mentor_student mentor = serializers.IntegerField(required=False, allow_null=True) student = serializers.IntegerField(required=False, allow_null=True) participant_ids = serializers.ListField( child=serializers.IntegerField(), required=False, allow_empty=True ) class Meta: model = Board fields = [ 'title', 'description', 'mentor', 'student', 'access_type', 'participant_ids', 'background_color', 'grid_enabled', 'width', 'height', 'is_template' ] def validate(self, attrs): """Валидация данных доски.""" # Для доски типа mentor_student требуются mentor и student if attrs.get('access_type') == 'mentor_student': if not attrs.get('mentor') or not attrs.get('student'): raise serializers.ValidationError( 'Для доски типа mentor_student требуются поля mentor и student' ) return attrs def create(self, validated_data): """Создание доски.""" from apps.users.models import User mentor_id = validated_data.pop('mentor', None) student_id = validated_data.pop('student', None) participant_ids = validated_data.pop('participant_ids', []) user = self.context['request'].user # Создаем доску board_data = { 'owner': user, **validated_data } # Добавляем ментора и студента if mentor_id: board_data['mentor_id'] = mentor_id if student_id: board_data['student_id'] = student_id board = Board.objects.create(**board_data) # Добавляем участников if participant_ids: participants = User.objects.filter(id__in=participant_ids) board.participants.set(participants) # Если указаны ментор и студент, добавляем их как участников if mentor_id or student_id: if mentor_id: board.participants.add(User.objects.get(id=mentor_id)) if student_id: board.participants.add(User.objects.get(id=student_id)) return board class BoardSnapshotSerializer(serializers.ModelSerializer): """Сериализатор снимка доски.""" created_by = UserSerializer(read_only=True) class Meta: model = BoardSnapshot fields = [ 'id', 'board', 'snapshot_data', 'created_by', 'description', 'created_at' ] read_only_fields = [ 'created_by', 'created_at' ] class BoardSnapshotCreateSerializer(serializers.ModelSerializer): """Сериализатор создания снимка доски.""" board_id = serializers.UUIDField(write_only=True) class Meta: model = BoardSnapshot fields = [ 'board_id', 'description' ] def validate_board_id(self, value): """Проверка доски.""" try: board = Board.objects.get(board_id=value) except Board.DoesNotExist: raise serializers.ValidationError('Доска не найдена') # Проверяем доступ user = self.context['request'].user if not board.has_access(user): raise serializers.ValidationError('У вас нет доступа к этой доске') return value def create(self, validated_data): """Создание снимка.""" board_id = validated_data.pop('board_id') board = Board.objects.get(board_id=board_id) user = self.context['request'].user # Собираем данные всех элементов elements = board.elements.filter(is_deleted=False) elements_data = BoardElementSerializer(elements, many=True).data snapshot_data = { 'board': BoardSerializer(board).data, 'elements': elements_data, 'timestamp': timezone.now().isoformat() } snapshot = BoardSnapshot.objects.create( board=board, created_by=user, snapshot_data=snapshot_data, **validated_data ) return snapshot