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

Как с помощью метода serializer создать модель?

1.6 Junior🔥 181 комментариев
#Django#REST API и HTTP

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

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

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

Как с помощью метода serializer создать модель в Django REST Framework

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

Базовая структура сериализатора

Создание простого сериализатора:

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

class UserSerializer(serializers.ModelSerializer):
    class Meta:
        model = User
        fields = ['id', 'username', 'email', 'first_name', 'last_name']
        read_only_fields = ['id']

# Использование для создания
serializer = UserSerializer(data={
    'username': 'john_doe',
    'email': 'john@example.com',
    'first_name': 'John',
    'last_name': 'Doe'
})

if serializer.is_valid():
    user = serializer.save()  # Создаёт User в БД
    print(f"User created: {user.id}")
else:
    print(f"Errors: {serializer.errors}")

Валидация перед сохранением

Добавление custom валидации:

class ProductSerializer(serializers.ModelSerializer):
    class Meta:
        model = Product
        fields = ['id', 'name', 'price', 'stock', 'category']
        read_only_fields = ['id']
    
    # 1. Field-level валидация
    def validate_price(self, value):
        if value <= 0:
            raise serializers.ValidationError("Price must be greater than 0")
        if value > 1000000:
            raise serializers.ValidationError("Price seems too high")
        return value
    
    def validate_stock(self, value):
        if value < 0:
            raise serializers.ValidationError("Stock cannot be negative")
        return value
    
    # 2. Object-level валидация
    def validate(self, data):
        if data['stock'] == 0 and data['price'] > 1000:
            raise serializers.ValidationError(
                "Cannot have zero stock for expensive products"
            )
        return data

# Использование
serializer = ProductSerializer(data={
    'name': 'Laptop',
    'price': 1500,
    'stock': 10,
    'category': 1
})

if serializer.is_valid():
    product = serializer.save()
    print(f"Product created: {product.name}")
else:
    print(f"Validation errors: {serializer.errors}")

Создание модели с вложенными данными

Работа с ForeignKey:

from django.db import models

class Author(models.Model):
    name = models.CharField(max_length=100)
    email = models.EmailField()

class Book(models.Model):
    title = models.CharField(max_length=200)
    author = models.ForeignKey(Author, on_delete=models.CASCADE)
    isbn = models.CharField(max_length=13)
    pages = models.IntegerField()

class AuthorSerializer(serializers.ModelSerializer):
    class Meta:
        model = Author
        fields = ['id', 'name', 'email']

class BookSerializer(serializers.ModelSerializer):
    author = AuthorSerializer()
    
    class Meta:
        model = Book
        fields = ['id', 'title', 'author', 'isbn', 'pages']
    
    def create(self, validated_data):
        author_data = validated_data.pop('author')
        author, created = Author.objects.get_or_create(**author_data)
        book = Book.objects.create(author=author, **validated_data)
        return book

# Использование
data = {
    'title': 'Python Advanced',
    'isbn': '9781234567890',
    'pages': 450,
    'author': {
        'name': 'Guido van Rossum',
        'email': 'guido@python.org'
    }
}

serializer = BookSerializer(data=data)
if serializer.is_valid():
    book = serializer.save()
    print(f"Book created: {book.title} by {book.author.name}")

Создание моделей с ManyToMany отношениями

Работа с множественными связями:

class Course(models.Model):
    title = models.CharField(max_length=100)

class Student(models.Model):
    name = models.CharField(max_length=100)
    courses = models.ManyToManyField(Course)

class StudentSerializer(serializers.ModelSerializer):
    courses = serializers.PrimaryKeyRelatedField(
        queryset=Course.objects.all(),
        many=True
    )
    
    class Meta:
        model = Student
        fields = ['id', 'name', 'courses']
    
    def create(self, validated_data):
        courses = validated_data.pop('courses')
        student = Student.objects.create(**validated_data)
        student.courses.set(courses)
        return student
    
    def update(self, instance, validated_data):
        courses = validated_data.pop('courses', None)
        for attr, value in validated_data.items():
            setattr(instance, attr, value)
        instance.save()
        if courses is not None:
            instance.courses.set(courses)
        return instance

# Использование
data = {
    'name': 'Alice',
    'courses': [1, 2, 3]
}

serializer = StudentSerializer(data=data)
if serializer.is_valid():
    student = serializer.save()
    print(f"Student {student.name} enrolled in {student.courses.count()} courses")

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

Добавление вычисляемых полей:

class OrderSerializer(serializers.ModelSerializer):
    total_price = serializers.SerializerMethodField()
    customer_name = serializers.CharField(source='customer.name', read_only=True)
    item_count = serializers.SerializerMethodField()
    
    class Meta:
        model = Order
        fields = ['id', 'customer_name', 'total_price', 'item_count', 'status']
    
    def get_total_price(self, obj):
        return obj.items.aggregate(total=models.Sum('price'))['total'] or 0
    
    def get_item_count(self, obj):
        return obj.items.count()

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

Создание моделей через APIView:

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

class CreateUserView(APIView):
    def post(self, request):
        serializer = UserSerializer(data=request.data)
        if serializer.is_valid():
            user = serializer.save()
            return Response(
                UserSerializer(user).data,
                status=status.HTTP_201_CREATED
            )
        return Response(
            serializer.errors,
            status=status.HTTP_400_BAD_REQUEST
        )

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

Более элегантный подход:

from rest_framework import viewsets

class UserViewSet(viewsets.ModelViewSet):
    queryset = User.objects.all()
    serializer_class = UserSerializer
    
    def perform_create(self, serializer):
        user = serializer.save()
        logger.info(f"User created: {user.id}")

# URL конфиг
from django.urls import path, include
from rest_framework.routers import DefaultRouter

router = DefaultRouter()
router.register(r'users', UserViewSet)

urlpatterns = [
    path('api/', include(router.urls)),
]

# Доступные endpoints:
# POST /api/users/ - создание
# GET /api/users/ - список
# PATCH /api/users/<id>/ - частичное обновление
# DELETE /api/users/<id>/ - удаление

Partial updates (частичное обновление)

Обновление только некоторых полей:

class PartialUserSerializer(serializers.ModelSerializer):
    class Meta:
        model = User
        fields = ['username', 'email', 'first_name']
    
    def update(self, instance, validated_data):
        instance.username = validated_data.get('username', instance.username)
        instance.email = validated_data.get('email', instance.email)
        instance.first_name = validated_data.get('first_name', instance.first_name)
        instance.save()
        return instance

# Использование
user = User.objects.first()
data = {'email': 'newemail@example.com'}

serializer = PartialUserSerializer(user, data=data, partial=True)
if serializer.is_valid():
    serializer.save()
    print(f"User updated: {serializer.data}")

Лучшие практики

  • Используй ModelSerializer для моделей
  • Раздели сериализаторы — read-only и write-only для разных операций
  • Валидируй на уровне сериализатора — безопаснее
  • SerializerMethodField для вычисляемых полей
  • Custom create/update когда нужна сложная логика
  • Документируй что какой сериализатор делает

Сериализаторы — это мост между API и БД, правильное их использование обеспечивает надёжное создание и обновление моделей.