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

Как создать сериализатор в Django?

1.8 Middle🔥 171 комментариев
#Django#REST API и HTTP

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

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

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

Как создать сериализатор в Django

Сериализатор в Django REST Framework (DRF) — это инструмент для преобразования данных между Python-объектами и JSON (или других форматов). Сериализаторы используются для валидации входных данных и сериализации выходных данных.

Установка

pip install djangorestframework

Базовый сериализатор

from rest_framework import serializers
from myapp.models import User

# Основанный на модели сериализатор
class UserSerializer(serializers.ModelSerializer):
    class Meta:
        model = User
        fields = ['id', 'username', 'email', 'first_name', 'last_name']

Это автоматически:

  • Создаёт поля на основе модели
  • Обеспечивает валидацию
  • Сериализует/десериализует данные

Полный пример с моделью

# models.py
from django.db import models

class User(models.Model):
    username = models.CharField(max_length=100, unique=True)
    email = models.EmailField()
    first_name = models.CharField(max_length=100)
    last_name = models.CharField(max_length=100)
    age = models.IntegerField(null=True, blank=True)
    created_at = models.DateTimeField(auto_now_add=True)
    
    def __str__(self):
        return self.username

# serializers.py
from rest_framework import serializers
from .models import User

class UserSerializer(serializers.ModelSerializer):
    class Meta:
        model = User
        fields = ['id', 'username', 'email', 'first_name', 'last_name', 'age']
        read_only_fields = ['id']  # id только для чтения

Использование в представлениях

# views.py
from rest_framework import viewsets
from rest_framework.response import Response
from rest_framework import status
from .models import User
from .serializers import UserSerializer

class UserViewSet(viewsets.ModelViewSet):
    queryset = User.objects.all()
    serializer_class = UserSerializer
    
    def create(self, request, *args, **kwargs):
        serializer = self.get_serializer(data=request.data)
        if serializer.is_valid():
            serializer.save()
            return Response(serializer.data, status=status.HTTP_201_CREATED)
        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

Пользовательские поля и валидация

from rest_framework import serializers
from .models import User

class UserSerializer(serializers.ModelSerializer):
    # Пользовательское поле
    full_name = serializers.SerializerMethodField()
    
    class Meta:
        model = User
        fields = ['id', 'username', 'email', 'first_name', 'last_name', 'age', 'full_name']
        read_only_fields = ['id', 'full_name']
    
    def get_full_name(self, obj):
        return f"{obj.first_name} {obj.last_name}"
    
    # Валидация отдельного поля
    def validate_email(self, value):
        if User.objects.filter(email=value).exists():
            raise serializers.ValidationError("Пользователь с этим email уже существует")
        return value
    
    # Валидация всего объекта
    def validate(self, data):
        if data['first_name'] == data['last_name']:
            raise serializers.ValidationError("Имя и фамилия не могут быть одинаковыми")
        return data

Сериализаторы без модели

Для данных, которые не связаны с моделью Django:

from rest_framework import serializers

class ContactSerializer(serializers.Serializer):
    name = serializers.CharField(max_length=100)
    email = serializers.EmailField()
    message = serializers.CharField()
    
    def validate_name(self, value):
        if len(value) < 2:
            raise serializers.ValidationError("Имя должно быть минимум 2 символа")
        return value

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

from rest_framework.response import Response
from rest_framework.decorators import api_view
from .serializers import ContactSerializer

@api_view(['POST'])
def send_contact(request):
    serializer = ContactSerializer(data=request.data)
    if serializer.is_valid():
        # Обработать данные
        return Response({"message": "Спасибо за сообщение"}, status=201)
    return Response(serializer.errors, status=400)

Вложенные сериализаторы

from rest_framework import serializers
from .models import User, Post

class PostSerializer(serializers.ModelSerializer):
    class Meta:
        model = Post
        fields = ['id', 'title', 'content']

class UserWithPostsSerializer(serializers.ModelSerializer):
    posts = PostSerializer(many=True, read_only=True)
    
    class Meta:
        model = User
        fields = ['id', 'username', 'email', 'posts']

PrimaryKeyRelatedField для связей

class PostSerializer(serializers.ModelSerializer):
    # Вместо вложенного сериализатора показываем только id автора
    author_id = serializers.PrimaryKeyRelatedField(
        queryset=User.objects.all(),
        source='author'
    )
    
    class Meta:
        model = Post
        fields = ['id', 'title', 'content', 'author_id']

Сериализация и десериализация

from .serializers import UserSerializer
from .models import User

# Сериализация (объект -> JSON)
user = User.objects.first()
serializer = UserSerializer(user)
print(serializer.data)  # {'id': 1, 'username': 'john', 'email': 'john@example.com', ...}

# Десериализация (JSON -> объект)
data = {'username': 'jane', 'email': 'jane@example.com', 'first_name': 'Jane'}
serializer = UserSerializer(data=data)
if serializer.is_valid():
    user = serializer.save()  # Создаёт объект User и сохраняет в БД
else:
    print(serializer.errors)  # Ошибки валидации

Динамические поля

class DynamicFieldsSerializer(serializers.ModelSerializer):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        
        request = self.context.get('request')
        if request:
            # ?fields=id,username,email
            fields = request.query_params.get('fields')
            if fields:
                allowed = set(fields.split(','))
                existing = set(self.fields.keys())
                for field_name in existing - allowed:
                    self.fields.pop(field_name)

class UserSerializer(DynamicFieldsSerializer):
    class Meta:
        model = User
        fields = ['id', 'username', 'email', 'first_name']

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

GET /api/users/?fields=id,username

Тестирование сериализаторов

from django.test import TestCase
from .serializers import UserSerializer
from .models import User

class UserSerializerTest(TestCase):
    def test_valid_serializer(self):
        data = {
            'username': 'testuser',
            'email': 'test@example.com',
            'first_name': 'Test',
            'last_name': 'User'
        }
        serializer = UserSerializer(data=data)
        self.assertTrue(serializer.is_valid())
    
    def test_invalid_email(self):
        data = {
            'username': 'testuser',
            'email': 'invalid-email',  # Неправильный email
            'first_name': 'Test',
            'last_name': 'User'
        }
        serializer = UserSerializer(data=data)
        self.assertFalse(serializer.is_valid())

Заключение

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

  • Автоматически валидируют входные данные
  • Преобразуют между Python-объектами и JSON
  • Поддерживают вложенные объекты и связи
  • Позволяют кастомизировать поля и валидацию
  • Интегрируются с viewsets для быстрого создания API