Разработка RESTful API с использованием Django REST Framework

Курс охватывает полный цикл создания веб-API: от настройки окружения и понимания архитектуры REST до реализации безопасности и автодокументации. Вы научитесь использовать сериализаторы, вьюсеты и маршрутизаторы для построения гибких сервисов [habr.com](https://habr.com/ru/companies/amvera/articles/856798).

1. Основы REST архитектуры и настройка проекта Django [mkdev.me](https://mkdev.me/ru/posts/chto-takoe-django-rest-framework)

Основы REST архитектуры и настройка проекта Django

Добро пожаловать в курс по разработке RESTful API. Это первая статья, в которой мы заложим фундамент для всей дальнейшей работы. Прежде чем писать код, необходимо разобраться, что именно мы строим и какие инструменты будем для этого использовать.

Мы начнем с теории архитектурного стиля REST, разберем ключевые принципы работы HTTP, а затем перейдем к практике: настройке окружения и созданию базового проекта на Django с подключением Django REST Framework (DRF).

Что такое REST и почему это стандарт?

REST (Representational State Transfer) — это не протокол и не библиотека. Это архитектурный стиль взаимодействия компонентов распределенного приложения в сети. Впервые этот термин был введен Роем Филдингом в 2000 году. Сегодня REST является стандартом де-факто для построения публичных API.

Основная идея REST заключается в том, что взаимодействие между клиентом (например, мобильным приложением или фронтендом на React) и сервером строится вокруг ресурсов. Ресурс — это любая информация, к которой можно дать имя: пользователь, товар, заказ, статья.

Ключевые принципы REST

Чтобы система считалась RESTful, она должна соответствовать ряду ограничений:

  • Клиент-серверная архитектура. Четкое разделение ответственности. Клиент занимается интерфейсом и взаимодействием с пользователем, сервер — хранением данных и бизнес-логикой. Это позволяет развивать их независимо друг от друга.
  • Stateless (Отсутствие состояния). Это критически важный принцип. Сервер не должен хранить информацию о состоянии сессии клиента между запросами. Каждый запрос от клиента должен содержать всю необходимую информацию для его обработки (включая данные для авторизации).
  • Единообразие интерфейса. Взаимодействие с ресурсами должно быть унифицированным. Неважно, запрашиваете вы данные о пользователе или о товаре — подход должен быть одинаковым (использование стандартных HTTP-методов).
  • Кэшируемость. Ответы сервера должны явно указывать, можно ли их кэшировать. Это снижает нагрузку на сеть и сервер.
  • Ресурсы и их представление

    В REST каждый ресурс имеет свой уникальный идентификатор — URI (Uniform Resource Identifier). Обычно это URL-адрес.

    Пример URI:

  • https://api.example.com/users/ — коллекция пользователей.
  • https://api.example.com/users/42/ — конкретный пользователь с ID 42.
  • Сервер не отдает клиенту базу данных напрямую. Он отдает представление ресурса. Самым популярным форматом обмена данными в современном вебе является JSON (JavaScript Object Notation), хотя REST не запрещает использование XML или HTML.

    Протокол HTTP: глаголы и коды состояний

    REST API опирается на протокол HTTP. Понимание методов (глаголов) и кодов ответов — это 50% успеха в проектировании API.

    HTTP Методы

    Методы определяют, какое действие мы хотим совершить над ресурсом.

    | Метод | Описание | Идемпотентность* | | :--- | :--- | :--- | | GET | Получение данных. Не изменяет состояние сервера. | Да | | POST | Создание нового ресурса. | Нет | | PUT | Полное обновление ресурса (заменяет объект целиком). | Да | | PATCH | Частичное обновление ресурса (меняет только переданные поля). | Нет (обычно) | | DELETE | Удаление ресурса. | Да |

    *Идемпотентность означает, что повторный идентичный запрос приведет к тому же состоянию сервера, что и одиночный запрос.

    Коды состояния HTTP

    Сервер всегда должен сообщать клиенту, как прошел запрос, используя числовые коды:

    * 2xx (Успех): * 200 OK: Запрос выполнен успешно (обычно для GET, PUT, PATCH). * 201 Created: Ресурс успешно создан (обычно ответ на POST). * 204 No Content: Успешно, но тела ответа нет (часто при DELETE). * 4xx (Ошибка клиента): * 400 Bad Request: Ошибка валидации данных или неверный синтаксис. * 401 Unauthorized: Пользователь не авторизован (нет токена). * 403 Forbidden: Авторизация есть, но нет прав на это действие. * 404 Not Found: Ресурс не найден. * 5xx (Ошибка сервера): * 500 Internal Server Error: Что-то сломалось на стороне бэкенда.

    Зачем нам Django REST Framework?

    Django сам по себе — мощный инструмент, но он изначально создавался для генерации HTML-страниц (паттерн MVT — Model-View-Template). Когда мы строим API, нам не нужны HTML-шаблоны, нам нужен JSON.

    Согласно mkdev.me: > Использование фреймворка позволяет сосредоточится на задачах бизнеса и не задумываться над техническими деталями там, где это возможно. Нужно отрисовать кнопку на сайте? Сделать авторизацию или сброс пароля? Сохранить данные пользователя из формы на сайте в базу данных? Для этого всё уже готово — бери и пользуйся!

    Django REST Framework (DRF) — это надстройка над Django, которая предоставляет инструменты специально для API:

  • Сериализаторы: Механизм превращения сложных типов данных (модели Django, QuerySet) в простые типы Python, которые легко конвертируются в JSON.
  • Аутентификация и права доступа: Готовые классы для настройки доступа (например, OAuth2, JWT).
  • Browsable API: Уникальная фича DRF — веб-интерфейс, который генерируется автоматически и позволяет тестировать ваше API прямо в браузере.
  • Практика: Настройка окружения и установка

    Перейдем от слов к делу. Мы создадим проект с нуля. Предполагается, что у вас уже установлен Python (версии 3.8 или выше).

    Шаг 1: Виртуальное окружение

    Никогда не устанавливайте пакеты глобально. Изоляция зависимостей — это база профессиональной разработки.

    Создадим папку проекта и виртуальное окружение:

    Активируем окружение:

    * Windows: venv\Scripts\activate * macOS/Linux: source venv/bin/activate

    Шаг 2: Установка зависимостей

    Нам понадобятся сам Django и библиотека djangorestframework. Обратите внимание на нейминг пакетов.

    Согласно habr.com: > Первое, что нас встречает - это установка пакета "djangorestframework" в виртуальную среду... Довольно неудобный и не запоминающийся нейминг для установки пакета, потому что далее для Django мы его подключаем как "rest_framework".

    Выполните команду:

    Шаг 3: Создание проекта

    Создадим стандартный проект Django. Не забудьте точку в конце команды, чтобы не создавать лишнюю вложенность папок.

    Теперь структура вашей папки должна выглядеть так:

    Шаг 4: Настройка settings.py

    Теперь самое важное. Нам нужно сообщить Django, что мы собираемся использовать DRF. Откройте файл config/settings.py и найдите список INSTALLED_APPS.

    Добавьте туда 'rest_framework':

    Также хорошей практикой является предварительная настройка конфигурации самого DRF. Добавьте этот словарь в конец файла settings.py:

    Разберем, что мы здесь написали: * DEFAULT_PERMISSION_CLASSES: Определяет политику доступа по умолчанию. AllowAny означает, что пока наше API открыто для всех (удобно для старта, но в будущем мы это изменим). * DEFAULT_RENDERER_CLASSES: Указывает, в каком виде отдавать данные. JSONRenderer — для программных клиентов, BrowsableAPIRenderer — для красивого интерфейса в браузере.

    Шаг 5: Проверка работоспособности

    Применим стандартные миграции (Django создает таблицы для пользователей и админки) и запустим сервер.

    Если вы видите сообщение: Starting development server at http://127.0.0.1:8000/

    Поздравляю! Вы успешно настроили базу для разработки REST API. Пока по этому адресу вы увидите стандартную стартовую страницу Django (ракету), так как мы еще не создали ни одного эндпоинта.

    Итоги

    В этой статье мы заложили теоретический и технический фундамент курса.

  • REST — это архитектурный стиль, основанный на ресурсах и отсутствии состояния (Stateless).
  • HTTP методы (GET, POST, PUT, DELETE) определяют действия над данными, а коды состояния (200, 404, 500) сообщают результат.
  • Django REST Framework — необходимый инструмент, который берет на себя сериализацию данных в JSON и обработку запросов.
  • Для начала работы необходимо установить пакет djangorestframework и добавить rest_framework в INSTALLED_APPS.
  • В следующей статье мы создадим нашу первую модель данных и напишем для нее сериализатор, чтобы получить первый реальный JSON-ответ от сервера.

    2. Сериализаторы: работа с данными и класс ModelSerializer [gitbook.io](https://ilyachch.gitbook.io/django-rest-framework-russian-documentation/overview/navigaciya-po-api/serializers)

    Сериализаторы: работа с данными и класс ModelSerializer

    Добро пожаловать во вторую часть курса по разработке RESTful API. В предыдущей статье мы настроили окружение и установили Django REST Framework (DRF). Теперь у нас есть пустой проект, готовый к работе.

    Однако, прежде чем мы сможем отправлять данные клиенту (например, мобильному приложению или фронтенду), нам нужно решить фундаментальную проблему: языковой барьер.

    База данных и Django оперируют сложными объектами Python (экземплярами моделей), а веб-клиенты понимают строки, чаще всего в формате JSON. Чтобы они поняли друг друга, нужен переводчик. В мире DRF этот переводчик называется Сериализатор.

    Что такое сериализация и десериализация?

    Глобально процесс обмена данными состоит из двух направлений:

  • Сериализация (Serialization) — процесс преобразования сложных структур данных (экземпляров моделей Django, QuerySet'ов) в простые типы данных Python (словари, списки, строки), которые затем легко конвертируются в JSON.
  • Направление:* Сервер -> Клиент (Чтение данных).
  • Десериализация (Deserialization) — обратный процесс. Мы получаем JSON от клиента, проверяем его валидность и преобразуем обратно в объекты Python для сохранения в базу данных.
  • Направление:* Клиент -> Сервер (Запись данных).

    Согласно ilyachch.gitbook.io: > Сериализаторы позволяют преобразовывать сложные данные, такие как наборы запросов и экземпляры моделей, в собственные типы данных Python, которые затем могут быть легко преобразованы в JSON, XML или другие типы содержимого.

    Создание первой модели

    Чтобы нам было что сериализовать, создадим простую модель. Допустим, мы делаем каталог книг. Откройте файл models.py в вашем приложении и добавьте следующий код:

    Не забудьте создать и применить миграции:

    Базовый класс Serializer

    В DRF есть два основных способа создания сериализаторов: Serializer и ModelSerializer. Начнем с базового класса Serializer, чтобы понять механику процесса. Это очень похоже на создание обычной формы Django (django.forms.Form).

    Создайте файл serializers.py в папке вашего приложения и добавьте туда код:

    Разбор кода

  • Дублирование полей: Мы вручную прописали те же поля, что и в модели. Это дает полный контроль, но нарушает принцип DRY (Don't Repeat Yourself).
  • Методы create и update: Базовый Serializer не знает, что делать с данными после валидации. Мы обязаны вручную описать логику сохранения в базу данных.
  • read_only=True: Мы указали, что id и published_date не нужно ждать от клиента — они генерируются автоматически.
  • Как это работает на практике?

    Давайте протестируем наш сериализатор через консоль (shell). Запустите python manage.py shell.

    1. Сериализация (из объекта в JSON):

    2. Десериализация (из JSON в объект):

    Обратите внимание: метод save() вызовет create(), если мы создаем новый объект, или update(), если мы передали существующий инстанс при инициализации.

    Класс ModelSerializer: магия автоматизации

    Писать поля вручную утомительно. Если ваш сериализатор напрямую связан с моделью Django (а это 95% случаев), используйте ModelSerializer.

    Перепишем наш serializers.py:

    Преимущества ModelSerializer

    Согласно ilyachch.gitbook.io: > Класс ModelSerializer предоставляет полезный ярлык для создания сериализаторов, работающих с экземплярами моделей и наборами запросов.

    Что он делает за нас:

  • Автоматическое создание полей: Он смотрит в модель Book, видит CharField и создает соответствующий serializers.CharField.
  • Валидаторы: Он переносит ограничения из модели. Если в модели title имеет max_length=100, сериализатор автоматически вернет ошибку, если прислать строку длиной 101 символ.
  • Реализация create() и update(): Нам больше не нужно писать методы сохранения вручную. DRF сделает стандартное сохранение (model.objects.create) за нас.
  • Настройка полей

    Даже используя ModelSerializer, вы можете переопределять поведение полей или добавлять новые.

    Пример добавления вычисляемого поля, которого нет в базе данных:

    Поле SerializerMethodField ищет метод с именем get_<имя_поля> и использует его результат как значение.

    Работа с коллекциями (many=True)

    Часто нам нужно отдать клиенту не одну книгу, а список всех книг. Сериализаторы умеют это делать «из коробки» с помощью аргумента many=True.

    Если вы забудете указать many=True при передаче QuerySet, DRF выдаст ошибку, так как будет ожидать один объект, а получит список.

    Валидация данных

    Валидация — критически важная часть десериализации. Метод .is_valid() запускает цепочку проверок:

  • Проверка типов: Является ли price числом?
  • Проверка ограничений: Не превышена ли длина строки? Не пустое ли обязательное поле?
  • Пользовательская валидация: Вы можете написать свои методы проверки.
  • Пример добавления проверки на уровне поля:

    Согласно django.fun: > Поля сериализатора выполняют преобразование между примитивными значениями и внутренними типами данных. Они также занимаются проверкой входных значений.

    Если is_valid() возвращает False, список ошибок доступен в атрибуте .errors. Это словарь, где ключи — названия полей, а значения — списки ошибок.

    Итоги

    Мы разобрали ключевой компонент DRF — сериализаторы. Без них невозможно построить API, так как они служат мостом между базой данных и внешним миром.

  • Сериализация превращает модели Django в JSON, десериализация превращает JSON в модели Django.
  • Класс Serializer дает полный контроль, но требует ручного описания всех полей и методов сохранения.
  • Класс ModelSerializer значительно ускоряет разработку, автоматически генерируя поля и валидаторы на основе модели Django.
  • Для обработки списка объектов необходимо передавать флаг many=True при инициализации сериализатора.
  • Перед сохранением данных всегда вызывайте метод .is_valid() для проверки корректности входящей информации.