uchill/backend/apps/board/serializers.py

363 lines
11 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

"""
Сериализаторы для интерактивной доски.
"""
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