← Назад к вопросам

Что представляют собой сериалайзеры?

2.0 Middle🔥 91 комментариев
#DevOps и инфраструктура

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI23 мар. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Сериализаторы в Python и веб-фреймворках

Что такое сериализация

Сериализация — это преобразование объектов из одного представления в другое. В веб-разработке это обычно означает преобразование данных Python-объектов в формат, пригодный для передачи (JSON, XML) или наоборот.

Сериализатор — это инструмент/класс, который выполняет это преобразование в обе стороны:

  • Сериализация (serialization): объект Python → JSON/словарь
  • Десериализация (deserialization): JSON/словарь → объект Python

Сериализация на чистом Python

Встроенный модуль json

import json

# Сериализация: объект → JSON строка
user_dict = {"id": 1, "name": "Иван", "email": "ivan@example.com"}
json_string = json.dumps(user_dict)
print(json_string)
# Результат: {"id": 1, "name": "Иван", "email": "ivan@example.com"}

# Десериализация: JSON строка → объект
loaded_data = json.loads(json_string)
print(loaded_data["name"])  # "Иван"

Проблема с json: он работает только со встроенными типами (dict, list, str, int, bool, None). Для сложных объектов нужны кастомные сериализаторы.

Кастомный сериализатор

from datetime import datetime
import json

class User:
    def __init__(self, id, name, email, created_at):
        self.id = id
        self.name = name
        self.email = email
        self.created_at = created_at

# Вариант 1: Переопределить __dict__ (простой, но ограниченный)
user = User(1, "Иван", "ivan@example.com", datetime.now())

# Это не сработает, потому что datetime не JSON-сериализуем
try:
    json.dumps(user.__dict__)
except TypeError as e:
    print(f"Ошибка: {e}")
    # TypeError: Object of type datetime is not JSON serializable

# Вариант 2: Использовать custom JSONEncoder
class UserEncoder(json.JSONEncoder):
    def default(self, obj):
        if isinstance(obj, User):
            return {
                "id": obj.id,
                "name": obj.name,
                "email": obj.email,
                "created_at": obj.created_at.isoformat()
            }
        elif isinstance(obj, datetime):
            return obj.isoformat()
        return super().default(obj)

json_string = json.dumps(user, cls=UserEncoder)
print(json_string)
# Результат: {"id": 1, "name": "Иван", "email": "ivan@example.com", "created_at": "2026-03-23T..."}

Сериализаторы в Django REST Framework

В веб-приложениях сериализаторы играют критическую роль. Django REST Framework предоставляет мощную систему сериализаторов.

Базовый Serializer

from rest_framework import serializers
from django.contrib.auth.models import User

class UserSerializer(serializers.Serializer):
    """Базовый сериализатор (не привязан к модели)"""
    id = serializers.IntegerField()
    name = serializers.CharField(max_length=100)
    email = serializers.EmailField()
    created_at = serializers.DateTimeField()
    
    def create(self, validated_data):
        """Создание объекта из валидных данных"""
        return User(**validated_data)
    
    def update(self, instance, validated_data):
        """Обновление существующего объекта"""
        instance.name = validated_data.get('name', instance.name)
        instance.email = validated_data.get('email', instance.email)
        instance.save()
        return instance

ModelSerializer (привязан к модели)

class UserModelSerializer(serializers.ModelSerializer):
    """Автоматически генерирует поля на основе модели"""
    class Meta:
        model = User
        fields = ['id', 'username', 'email', 'date_joined']
        read_only_fields = ['id', 'date_joined']  # Нельзя менять
        extra_kwargs = {
            'email': {'required': True},
            'username': {'min_length': 3}
        }

Использование в View

from rest_framework.response import Response
from rest_framework.views import APIView

class UserListView(APIView):
    def get(self, request):
        """Получить список пользователей (сериализация)"""
        users = User.objects.all()
        serializer = UserModelSerializer(users, many=True)
        return Response(serializer.data)
    
    def post(self, request):
        """Создать пользователя (десериализация + валидация)"""
        serializer = UserModelSerializer(data=request.data)
        if serializer.is_valid():
            serializer.save()  # Вызовет create() метод
            return Response(serializer.data, status=201)
        return Response(serializer.errors, status=400)

Валидация в сериализаторах

class PostSerializer(serializers.ModelSerializer):
    class Meta:
        model = Post
        fields = ['id', 'title', 'content', 'author']
    
    # Валидация отдельного поля
    def validate_title(self, value):
        if len(value) < 3:
            raise serializers.ValidationError("Заголовок слишком короткий")
        return value
    
    # Валидация нескольких полей вместе
    def validate(self, data):
        if data['title'].lower() == data['content'].lower():
            raise serializers.ValidationError(
                "Заголовок и контент не должны быть одинаковыми"
            )
        return data

Nested сериализаторы

class CommentSerializer(serializers.ModelSerializer):
    class Meta:
        model = Comment
        fields = ['id', 'text', 'author']

class PostDetailSerializer(serializers.ModelSerializer):
    """Пост с вложенными комментариями"""
    comments = CommentSerializer(many=True, read_only=True)
    author = UserModelSerializer(read_only=True)
    
    class Meta:
        model = Post
        fields = ['id', 'title', 'content', 'author', 'comments']

# Результат:
# {
#     "id": 1,
#     "title": "Заголовок",
#     "content": "Контент",
#     "author": {"id": 1, "username": "ivan", "email": "ivan@example.com"},
#     "comments": [
#         {"id": 1, "text": "Спасибо!", "author": 2},
#         {"id": 2, "text": "Интересно", "author": 3}
#     ]
# }

Производительность: source и SlugRelatedField

class OptimizedPostSerializer(serializers.ModelSerializer):
    """Сериализатор с оптимизацией"""
    author_name = serializers.CharField(source='author.username', read_only=True)
    author_id = serializers.PrimaryKeyRelatedField(
        source='author',
        read_only=True
    )
    
    class Meta:
        model = Post
        fields = ['id', 'title', 'author_id', 'author_name']

Итог

Сериализаторы — это инструмент для преобразования данных:

  1. Сериализация: Python-объекты → JSON (для отправки в API)
  2. Десериализация: JSON → Python-объекты (для создания/обновления)
  3. Валидация: проверка данных перед сохранением
  4. Трансформация: доступ к вложенным полям (nested serializers)

В Django REST Framework сериализаторы — это основа API. Они обеспечивают типизацию, валидацию и преобразование данных, упрощая разработку и поддержку REST API.