JavaRush /Курсы /Модуль 3: Django /Практическое занятие по созданию и использованию сериализ...

Практическое занятие по созданию и использованию сериализаторов

Модуль 3: Django
17 уровень , 9 лекция
Открыта

Давайте создадим небольшое API для управления библиотекой книг. В нашем API будет реализована работа с книгами и авторами, включая CRUD-операции, а также будем работать с вложенными сериализаторами, валидацией и кастомизацией.

Основные моменты, которые будут затронуты:

  1. Работа с ModelSerializer для упрощения сериализации.
  2. Использование вложенных сериализаторов.
  3. Валидация данных.
  4. Кастомизация методов сериализаторов: create(), update().
  5. Использование метода to_representation() для изменения выходного формата.

Поднимем свои навыки сериализации на новый уровень, чтобы вы стали мастером этого искусства!

Подготовка проекта

Перед началом работы убедимся, что у нас есть базовое Django-приложение с установленным Django REST Framework. Если вы только присоединились, ниже указаны шаги для создания окружения:

  1. Установите Django и DRF:
    pip install django djangorestframework
    
  2. Создайте Django-проект и приложение:
    django-admin startproject library
    cd library
    python manage.py startapp books
    
  3. Зарегистрируйте приложение books в настройках INSTALLED_APPS вашего settings.py:
    INSTALLED_APPS = [
        ...
        'rest_framework',
        'books',
    ]
    

Теперь приступим к созданию моделей и API!

Шаг 1. Модели для приложения "Библиотека"

Мы начнем с создания двух моделей: Author и Book. Модель Author будет описывать авторов книг, а модель Book — сами книги. Книга будет связана с автором через поле ForeignKey.

# books/models.py

from django.db import models

class Author(models.Model):
    first_name = models.CharField(max_length=100)
    last_name = models.CharField(max_length=100)
    birth_date = models.DateField(null=True, blank=True)

    def __str__(self):
        return f"{self.first_name} {self.last_name}"

class Book(models.Model):
    title = models.CharField(max_length=200)
    description = models.TextField(blank=True)
    author = models.ForeignKey(Author, related_name='books', on_delete=models.CASCADE)

    def __str__(self):
        return self.title

Запустите миграции:

python manage.py makemigrations
python manage.py migrate

Шаг 2. Создание сериализатора для модели Author

Создадим сериализатор для модели Author. Начнем с базового ModelSerializer и настроим поля.

# books/serializers.py

from rest_framework import serializers
from .models import Author

class AuthorSerializer(serializers.ModelSerializer):
    class Meta:
        model = Author
        fields = ['id', 'first_name', 'last_name', 'birth_date']

Этот сериализатор позволит нам преобразовывать данные авторов в JSON и обратно.

Шаг 3. Сериализатор для модели Book с вложенным автором

Теперь создадим сериализатор для модели Book. Мы добавим вложенный сериализатор для представления информации об авторе.

# books/serializers.py

from .models import Book

class BookSerializer(serializers.ModelSerializer):
    author = AuthorSerializer()  # Вложенный сериализатор

    class Meta:
        model = Book
        fields = ['id', 'title', 'description', 'author']

Этот сериализатор позволит нам отображать данные о книге, включая информацию об авторе, в одном запросе.

Шаг 4. Переопределение метода create()

Сейчас наш сериализатор BookSerializer "не умеет" автоматически создавать автора при добавлении книги. Исправим это, переопределив метод create().

class BookSerializer(serializers.ModelSerializer):
    author = AuthorSerializer()  # Вложенный сериализатор

    class Meta:
        model = Book
        fields = ['id', 'title', 'description', 'author']

    def create(self, validated_data):
        author_data = validated_data.pop('author')  # Извлекаем данные автора
        author = Author.objects.create(**author_data)  # Создаем автора
        book = Book.objects.create(author=author, **validated_data)  # Создаем книгу
        return book

Теперь наш сериализатор может не только обрабатывать книги, но и "размножать" авторов по ходу дела.

Шаг 5. Валидация данных

Добавим пользовательскую валидацию для модели Author. Например, проверим, чтобы поле first_name не было пустым и не содержало только пробелы.

class AuthorSerializer(serializers.ModelSerializer):
    class Meta:
        model = Author
        fields = ['id', 'first_name', 'last_name', 'birth_date']

    def validate_first_name(self, value):
        if not value.strip():  # Проверяем, не состоит ли значение из пробелов
            raise serializers.ValidationError("Имя автора не может быть пустым!")
        return value

Шаг 6. Метод to_representation() для кастомизации вывода

Иногда нам нужно преобразовать данные перед их отправкой клиенту. Например, добавим полное имя автора в вывод.

class AuthorSerializer(serializers.ModelSerializer):
    full_name = serializers.SerializerMethodField()

    class Meta:
        model = Author
        fields = ['id', 'first_name', 'last_name', 'birth_date', 'full_name']

    def get_full_name(self, obj):
        return f"{obj.first_name} {obj.last_name}"

Теперь поле full_name автоматически добавляется при выводе данных об авторе.

Шаг 7. APIView для работы с книгами

Мы используем DRF представление для обработки запросов. Создадим простое API для работы с книгами.

# books/views.py

from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework import status
from .models import Book
from .serializers import BookSerializer

class BookListCreateAPIView(APIView):
    def get(self, request):
        books = Book.objects.all()
        serializer = BookSerializer(books, many=True)
        return Response(serializer.data)

    def post(self, request):
        serializer = BookSerializer(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)

Шаг 8. Маршруты

Настроим маршруты для нашего API.

# books/urls.py

from django.urls import path
from .views import BookListCreateAPIView

urlpatterns = [
    path('books/', BookListCreateAPIView.as_view(), name='book-list-create'),
]

Не забудьте подключить их в основном urls.py проекта.

Шаг 9. Тестирование API

Поднимите локальный сервер:

python manage.py runserver

Теперь вы можете:

  1. Отправить GET-запрос на /books/ и получить список книг.
  2. Отправить POST-запрос на /books/ с данными книги и автора, чтобы создать их.

Пример тела POST-запроса:

{
    "title": "1984",
    "description": "Дистопический роман",
    "author": {
        "first_name": "Джордж",
        "last_name": "Оруэлл",
        "birth_date": "1903-06-25"
    }
}

Теперь у вас есть мощный инструмент для работы с данными через Django REST Framework! Развивайте свой API и не забывайте экспериментировать!

1
Задача
Модуль 3: Django, 17 уровень, 9 лекция
Недоступна
Создание API для управления заказами
Создание API для управления заказами
1
Задача
Модуль 3: Django, 17 уровень, 9 лекция
Недоступна
Валидация данных в сериализаторе для модели "Event"
Валидация данных в сериализаторе для модели "Event"
3
Опрос
Сериализация связанных объектов, 17 уровень, 9 лекция
Недоступен
Сериализация связанных объектов
Сериализация связанных объектов
Комментарии
ЧТОБЫ ПОСМОТРЕТЬ ВСЕ КОММЕНТАРИИ ИЛИ ОСТАВИТЬ КОММЕНТАРИЙ,
ПЕРЕЙДИТЕ В ПОЛНУЮ ВЕРСИЮ