Давайте создадим небольшое API для управления библиотекой книг. В нашем API будет реализована работа с книгами и авторами, включая CRUD-операции, а также будем работать с вложенными сериализаторами, валидацией и кастомизацией.
Основные моменты, которые будут затронуты:
- Работа с
ModelSerializerдля упрощения сериализации. - Использование вложенных сериализаторов.
- Валидация данных.
- Кастомизация методов сериализаторов:
create(),update(). - Использование метода
to_representation()для изменения выходного формата.
Поднимем свои навыки сериализации на новый уровень, чтобы вы стали мастером этого искусства!
Подготовка проекта
Перед началом работы убедимся, что у нас есть базовое Django-приложение с установленным Django REST Framework. Если вы только присоединились, ниже указаны шаги для создания окружения:
- Установите Django и DRF:
pip install django djangorestframework - Создайте Django-проект и приложение:
django-admin startproject library cd library python manage.py startapp books - Зарегистрируйте приложение
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
Теперь вы можете:
- Отправить GET-запрос на
/books/и получить список книг. - Отправить POST-запрос на
/books/с данными книги и автора, чтобы создать их.
Пример тела POST-запроса:
{
"title": "1984",
"description": "Дистопический роман",
"author": {
"first_name": "Джордж",
"last_name": "Оруэлл",
"birth_date": "1903-06-25"
}
}
Теперь у вас есть мощный инструмент для работы с данными через Django REST Framework! Развивайте свой API и не забывайте экспериментировать!
ПЕРЕЙДИТЕ В ПОЛНУЮ ВЕРСИЮ