Что представляют собой сериалайзеры?
Комментарии (1)
Ответ сгенерирован нейросетью и может содержать ошибки
Сериализаторы в 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']
Итог
Сериализаторы — это инструмент для преобразования данных:
- Сериализация: Python-объекты → JSON (для отправки в API)
- Десериализация: JSON → Python-объекты (для создания/обновления)
- Валидация: проверка данных перед сохранением
- Трансформация: доступ к вложенным полям (nested serializers)
В Django REST Framework сериализаторы — это основа API. Они обеспечивают типизацию, валидацию и преобразование данных, упрощая разработку и поддержку REST API.