Django rest framework запросы

Обновлено: 02.07.2024

Урок 2: Запросы и ответы

С этого момента мы начнем изучать ядро DRF. Давайте рассмотрим пару основных блоков.

Также DRF предоставляет объект Response, являющийся расширением TemplateResponse, который берет сырые данные и использует их для определения и формирование правильного типа контента, возвращаемого клиенту.

DRF предоставляет два способа обозначения представлений API:

  • декоратор @api_view для работы с представлениями-функциями;
  • класс APIView для наследования при работе с представлениями-классами.

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

Так же они предоставляют такой функционал, как возврат 405 Method Not Allowed ответа, когда это необходимо, и обработку ошибок ParseError , когда данные в request.data неверно сформированы.

Собираем все вместе

Давайте начнем использовать эти компоненты, чтобы написать несколько представлений.

Мы больше не нуждаемся в классе JSONResponse в модуле views.py , так что можно его удалить. Когда это будет сделано, мы можем продолжить переписывать наши представления.

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

Здесь у нас представление отдельного сниппета.

Это не должно быть слишком сложным для понимания - оно практически не отличается от работы с обычными Django представлениями.

Обратите внимание, что мы больше не привязываем наши запросы и ответы к определенному типу контента. Request.data может обрабатывать входящие запросы как в формате json, так и в других форматах. Точно так же мы возвращаем объекты Response с данными, но позволяем DRF формировать данные в правильный тип.

Добавление определителей формата в URL

Начнем с того, что добавим именованный параметр к нашим представлениям

Теперь необходимо обновить urls.py , добавив format_suffix_patterns в дополнение к уже имеющимся представлениям.

Нам не нужно добавлять еще один параметр URL - у нас есть возможность просто и аккуратно сослаться на необходимый формат.

Как это выглядит

Проверьте работу API из командной строки, как это делалось в Уроке 1. Все работает одинаково, при этом мы получили улучшенную обработку ошибок в случае отправки неверных запросов.

Мы можем получить список всех сниппетов, как и раньше.

Мы можем управлять форматом ответа, используя заголовок Accept :

Или с помощью добавления в конец расширения файла для формата:

Так же мы можем управлять форматом запроса, который мы отправили, используя заголовок Content-Type .

Если вы используете ключ --debug , вы сможете увидеть тип запроса в заголовках запроса.

Поскольку API выбирает тип ответа, основываясь на запросе клиента, оно будет, по умолчанию, возвращать HTML версию запрашиваемого ресурса, когда запрос будет происходить из браузера. Это позволяет API формировать полностью браузерную версию данных.

Иметь браузерную версию API - огромное преимущество, поскольку значительно облегчает разработку. Также, это снижает порог входа в разработку как разрабатывающим API, так и разрабатывающим клиенты на основе этого API.

В уроке 3, мы будем использовать представления-классы(class-based views, CBV) и посмотрим, как встроенные представления уменьшат количество необходимого кода.

Меня зовут Стас Гаранжа, я выпускник курса «Python-разработчик» в Яндекс.Практикуме. Я хочу помочь начинающим разработчикам, которые приступили к изучению Django Rest Framework (DRF) и хотят разобраться, как устроен этот фреймворк.

Я готовлю цикл статей, в которых расскажу о разных сторонах работы DRF. У меня пока нет значимого практического опыта для описания всех изюминок при работе с этим фреймворком, поэтому в основе статьи — исследование, обобщение и по возможности непротиворечивое изложение того, что у DRF под капотом.

В этой статье разберёмся, как сделать REST API на базе Django Rest Framework, чтобы получить по GET-запросу набор записей из базы данных (БД). Иными словами, рассмотрим, как DRF работает на чтение (о том, как с помощью него создавать, изменять и удалять записи в БД, поговорим в отдельной статье).

Общую схему решения этой задачи мы рассмотрим в первой части статьи. Вторая будет посвящена детальному разбору процесса сериализации данных.

Несколько вводных замечаний:

  • Учебный проект, на основе которого даны все примеры в статье, можно найти в репозитории на Гитхабе.
  • Стиль и объём изложения рассчитаны на тех, кто не знаком с DRF и только начинает свой путь в разработке.
  • Предполагается, что читатель в общих чертах уже знаком с Django и знает основы ООП на Python.

Надеюсь, статья станет хорошим подспорьем изучения DRF и работы с его документацией, прояснит процесс сериализации данных и даст уверенность, что любая магия исчезает, стоит только покопаться под капотом конкретной библиотеки.

API для сайта на Django: общая схема

Задача

id country capital_city capital_population author (FK)
1 Norway Oslo 693500 1
2 Sweden Stockholm 961600 1
3 Finland Helsinki 655300 1
4 Iceland Reykjavik 128800 1

Поле author через внешний ключ (foreign key) связано с моделью User, в которой есть вся информация о пользователе с конкретным id.

Мы хотим получить информацию из базы данных, не открывая сайт в браузере, а сделав запрос из другого Python-приложения.

В каком виде нужно получить информацию:

  • Набор информации должен быть списком из Python-словарей: ключ — название поля записи в таблице Capital, значение — содержимое конкретного поля.
  • Названия стран нас не интересуют — нам нужны названия столиц, численность населения, а также имя сотрудника, который внёс запись в базу. Имя получаем через id автора, указанный в поле author .
  • Для передачи по сети полученные из БД данные должны быть конвертированы в json-формат.

Таким образом, каждую запись, которая при извлечении из базы данных является Python-объектом, принимающее приложение после декодирования json-строки должно получать в виде словаря:

В этом и состоит одно из назначений API — дать возможность различным приложениям доставать из БД сайта информацию в виде структуры данных, которую дальше можно обрабатывать.

Решаем задачу с помощью Django Rest Framework

Задача решается в два шага:

  • Сложный объект (набор записей из Django-модели) нужно превратить в более простую структуру, в нашем случае в список словарей. Понадобится сериалайзер.
  • Сериализованные данные для дальнейшей передачи по сети нужно перевести (отрендерить) в json-формат — универсальный текстовый формат передачи данных, не зависящий от языка реализации. Понадобится рендер.

Небольшое отступление о json. Базовые структуры данных на python кодируются в json и декодируются обратно следующим образом:

Python JSON Пример Python Пример JSON
dict object
list, tuple array ['элемент1', 'элемент2'], ('элемент1', 'элемент2') ["элемент1", "элемент2"]
str string 'элемент1' "элемент1"
int, float, int- & float-derived Enums number 5, 4.2 5, 4.2
True true True true
False false False false
None null None null

Создаём сериалайзер

Каждая запись в таблице Capital — объект. И как у любого объекта, у записи есть свои атрибуты. Изучим их на примере первой записи о столице Норвегии, воспользовавшись атрибутом __dict__ . Нам доступен словарь, который хранит информацию о динамических (writable) атрибутах объекта:

Каждое поле модели Capital — атрибут объекта конкретной записи. При этом поле author , которое через внешний ключ связано с моделью User и содержит id объектов из неё, в атрибуте записи и в БД получает приставку _id .

Сериалайзер поможет достать данные из нужных атрибутов (полей) записи и сформировать упорядоченный python-словарь — объект класса OrderedDict . Отмечу, что в Python с версии 3.7 и «обычные» словари стали сохранять порядок вставки пар «ключ — значение».

Для сериалайзера нужно описать поля: каждое поле будет отвечать за извлечение и представление данных из корреспондирующего поля табличной записи.

Важный момент: здесь мы рассматриваем сериалайзер на основе базового класса Serializer , чтобы лучше понять принципы его работы. На более высоком уровне абстракции есть класс ModelSerializer , который позволяет частично уйти от ручного создания полей. В этой статье он не рассматривается.

Нас интересуют данные, которые есть в трёх полях каждой табличной записи:

  • поле capital_city ,
  • поле capital_population ,
  • поле author .

Значит, в сериалайзере должно быть тоже три атрибута-поля.

При создании поля сериалайзера нужно определиться с названием поля и его типом. Назвать поля сериалайзера можно как угодно: именно эти названия будут ключами в словаре, в который сериалайзер преобразует запись из таблицы.

Вот примеры трёх вариантов названий полей сериалайзера:


Но как сериалайзер понимает, в каком порядке стыковать собственные поля с полями табличной записи? Например, если поле сериалайзера условно называется a , то как он определяет, что его нужно состыковать с полем записи capital_city ?

Теперь нужно выбрать тип поля сериалайзера. Его нужно соотнести с тем, какие данные извлекаются из корреспондирующего поля табличной записи. Дело в том, что у каждого поля сериалайзера есть собственный метод to_representation . Как следует из названия, задача метода — представить извлечённые из записи данные в определённом виде.

Например, есть поле serializers.IntegerField . Посмотрим на его метод to_representation :

Очевидно, этот тип поля сериалайзера нельзя выбирать для данных из табличной записи о названии столицы: int('Осло') вызовет ValueError. А вот для данных о численности населения — самое то.

Выберем следующие типы полей сериалайзера:

О соотношении полей сериалайзера и полей Django-моделей можно прочитать в документации DRF.

Код сериалайзера разместим в том же приложении, где находится Django-модель, под именем serializers.py:

В поле CharField указан необязательный параметр max_length , благодаря которому задаётся максимально допустимая длина передаваемого значения. О других параметрах поля написано в документации.

Пропущенный через сериалайзер набор табличных записей доступен в атрибуте сериалайзера data . Посмотрим на содержимое этого атрибута, создав тестовый вариант сериалайзера.

Сериалайзер в действии

Обратимся к файлу serializer_example_1.py . Он имитирует работу сериалайзера без необходимости запускать сервер и делать запрос к сайту. После клонирования учебного проекта и установки зависимостей (шаги 1—6 из ридми) достаточно запустить файл как обычный Python-скрипт и посмотреть в консоли результат его работы.

В serializer_example_1.py созданы классы с данными об авторах и о столицах для записей в таблицах:

Созданы объекты соответствующих записей:

Объединены записи в список по подобию кверисета из Django-модели:

Объявлен класс сериалайзера: код идентичен тому, который был приведён выше для class CapitalSerializer(serializers.Serializer) . Затем создали его экземпляр:

При создании мы передали сериалайзеру набор записей, которые нужно преобразовать. Они передаются в аргументе instance .

Кроме того, мы указали аргумент many со значением True . Дело в том, что логика работы сериалайзера с одной записью и с набором записей разная. Указывая many=True , мы включаем логику обработки набора записей. В чём она заключается, расскажу во второй части статьи при детальном разборе работы сериалайзера.

Выведем в консоль содержимое атрибута data сериалайзера:

Каждая запись из набора превратилась в упорядоченный словарь класса OrderedDict . Он находится в Python-модуле collections . Поэтому, если взглянуть на строки импорта в исходном коде restframework.serializers , можно увидеть:

В каждом OrderedDict содержится информация только из тех полей табличных записей, которые были состыкованы с полями сериалайзера. Данных о содержимом поля country нет — сериалайзер не настроен доставать эту информацию, потому что мы не создавали корреспондирующего поля в сериалайзере.

Отображаем (рендерим) информацию в формате json

Нам понадобится рендер — объект класса JSONRenderer . В файле serializer_example_2.py мы дополнили импорт — помимо модуля сериалайзеров из restframework мы импортировали модуль рендеров.

Далее необходимо создать экземпляр рендера нужного типа и вызвать у него метод render :

В результате мы увидим байтовую строку с массивом json-объектов:

Эта байтовая строка и будет передаваться по сети в атрибуте ответа content , а принимающее приложение будет её декодировать в список из Python-словарей и вытаскивать нужную информацию из каждого.

Что нужно ещё

Итак, мы испытали сериалайзер и посмотрели, как пропущенный через него набор табличных записей был преобразован в json-формат.

Чтобы сайт начал отдавать сериализованные данные, остаётся описать контроллер (view) и указать url-маршрут — эндпоинт, при обращении к которому сайт будет отдавать данные о столичных городах.

Контроллер

Во views.py создадим класс контроллера. Нам понадобятся следующие инструменты DRF:

Внутри контроллера описываем один метод — get. Почему он называется именно так?

Пример: если поступил GET-запрос, то будет задействован метод get контроллера.

В методе get опишем ту же логику, что и в файле с пробным запуском сериалайзера:

  1. Подготовить набор записей.
  2. Создать экземпляр сериалайзера, который может обрабатывать не отдельную запись, а их набор ( many=True ).
  3. Отрендерить в json-формат данные, полученные от сериалайзера.

В отличие от файла serializer_example_2.py , где мы явно прописывали json-рендер и вызывали у него метод render , в коде контроллера ничего такого нет. Но рендер всё равно отработает: его работа описана под капотом внутри класса-родителя APIView .

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

  1. Объект ответа, который вернул метод get ( return Response( ), передаётся в метод finalize_response родительского класса APIView .
  2. В методе finalize_response объекту ответа добавляются атрибуты:
    • accepted_renderer — им как раз выступает объект JSONRenderer,
    • accepted_media_type — 'application/json',
    • context .

Благодаря этим атрибутам формируется rendered_content : у экземпляра JSONRenderer срабатывает метод render , который возвращает байтовую строку с данными в json-формат. Она помещается в атрибут ответа content .

Маршрут (эндпоинт)

Здесь та же схема действий, как в классическом Django. Подключаем маршруты приложения capitals:

Прописываем сам маршрут в приложении capitals и связываем маршрут с контроллером:

API в действии

Чтобы посмотреть, как работает API, можно:

Осталось выполнить шаги 2 и 3.

Если всё отработало штатно, в корневой директории проекта появится файл capitals.txt со следующим содержимым:

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

Browsable API — удобный инструмент для тестирования API на DRF

Django Rest Framework позволяет посмотреть в браузере, какую информацию будет отдавать API при обращении к конкретному маршруту (эндпоинту). Достаточно ввести маршрут в адресную строку, и откроется страница с данными о запросе и результате его выполнения. За такое отображение отвечает BrowsableAPIRenderer.


Итак, мы рассмотрели, как сделать API на базе DRF, чтобы получить по GET-запросу набор записей из Django-модели. Во второй части подробно разберём работу сериалайзера на чтение.
Если у вас появились вопросы по решению задачи, пишите в комментариях.

Django REST Framework: REST API на Python с нуля

Термин REST API расшифровывается как Representational State Transfer Application Programming Interface. Следовательно, RESTful API — это программный интерфейс приложения, соответствующий ограничениям архитектурного стиля REST.

REST — не протокол и не стандарт. Это, как уже было сказано, архитектурное ограничение. Чтобы API считался RESTful, он должен соответствовать следующим критериям.

Благодаря вышеперечисленным архитектурным правилам REST API масштабируемый, переносимый и гибкий.

2. Что такое Django REST Framework?

Django — масштабируемый полнофункциональный веб-фреймворк, написанный на Python. Django берет на себя все хлопоты, зачастую связанные с веб-разработкой, такие как безопасность и доступ к базам данных.

Существует множество библиотек для Django, расширяющих его функционал. Одна из них, о которой мы поговорим сегодня, — это Django REST Framework или DRF, которая позволяет сериализовать данные из Django ORM через REST API.

Сериализация — это преобразование таблиц из базы данных в формат JSON.

Руководство написано для новичков, прошлый опыт работы с фреймворком Django не предполагается, так как вы многому научитесь прямо сейчас. Кроме того, в статье не будет обширного описания технических нюансов каждой операции. Рассматривайте руководство в качестве упражнения.

Давайте создадим сайт бронирования отелей! Исходный код и справка доступны на GitHub.

3. Установка Django

Прежде чем приступить непосредственно к работе с REST API, сделаем краткий экскурс в Django.

3.1. Создание виртуальной среды

3.2. Установка зависимостей

3.3. Начало проекта

3.4. Изменение директории

3.5. Запуск сервера


3.6. Создание приложения

Приложения в Django — это независимые многократно используемые компоненты. Создадим приложение hotel_app .

3.7. Список приложений в проекте

Чтобы подключить к проекту hotel_reservation приложения hotel_app и rest_framework , необходимо отредактировать файл results/settings.py , указав эти приложения в списке INSTALLED_APPS :

3.8. Миграции

Теперь нужно выполнить Django-миграции — это способ Django распространять в схему базы данных все изменения, вносимые в модели, такие как добавление поля, удаление модели. Выполняйте эту команду каждый раз, когда модель или база данных сколько-нибудь меняются:

3.9. Административная панель

Django поставляется со встроенной панелью администратора, что позволяет создать суперпользователя с помощью одной команды. Заполните форму — появится учетная запись администратора:


Снова выполните миграции, авторизуйтесь.


3.10. Создание модели

Django ORM абстрагирует базу данных, позволяя легко запрашивать данные и манипулировать ими через объектно-ориентированное отображение, называемое моделью. Django ORM заставляет писать код согласно паттерну MVC (Model View Controller), который станет интуитивно понятным для вас после прохождения кривой обучения.

hotel_app/models.py :

Мы создали модель, хранящую имя студента и его оценки. Метод __str__ определяет имя объекта, отображаемое в браузере. Если пропустить определение данного метода, то вы увидите в панели администратора объект под названием <ClassName> .

3.11. Не забывайте о миграциях!

Теперь, когда изменения уже внесены в модель, настало время выполнить миграции.

3.12. Добавление приложения в админ-панель

Во встроенное приложение административной панели можно добавить созданную ранее пользовательскую модель.

hotel_app/admin.py :


Теперь мы завершили ту общую часть разработки веб-приложения, которая относится к фреймворку Django. Настало время приступить к проектированию REST API.

4. Написание Django REST API

Структура директорий проекта:

Добавим в проект файлы urls.py и serializers.py . Вот новый список файлов.

4.1. Сериализатор

Сериализация — процесс перевода структуры данных в последовательность байтов. Она используется для передачи объектов по сети и для сохранения их в файлы (Википедия).

hotel_app/serializers.py :

Сериализаторы определяют, как именно и какие данные отобразит представление API. При запросе по REST API к экземпляру модели Hotel мы получим список следующих полей, взятых из самой модели при помощи сериализатора:

4.2. Представления

Файл представления определяет то, как сериализованные объекты отображаются пользователю.

4.3. URL: ссылки на ресурсы

hotel_app/urls.py :

hotel_reservation/urls.py :

Перейдя по данной ссылке, вы получите доступ ко всем ранее определенным “разделам” REST API проекта:


5. Выводы

API-сервисы позволяют приложениям общаться с другими приложения с помощью данных, передаваемых в формате JSON. Достаточно создать и использовать его данные из любого API-клиента или фронтенд-приложения.

Django REST Framework — это набор инструментов для создания REST API с помощью Django. В этом руководстве рассмотрим, как правильно его использовать. Создадим эндпоинты(точки доступа к ресурсам) для пользователей, постов в блоге, комментариев и категорий.

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

Вот чему вы научитесь:

  • Добавлять новые и существующие модели Django в API.
  • Сериализовать модели с помощью встроенных сериализаторов для распространенных API-паттернов.
  • Создавать представления и URL-паттерны.
  • Создавать отношения многие-к-одному и многие-ко-многим.
  • Аутентифицировать пользовательские действия.
  • Использовать созданный API Django REST Framework.

Требования

У вас в системе должен быть установлен Python 3, желательно 3.8. Также понадобится опыт работы с REST API. Вы должны быть знакомы с реляционными базами данными, включая основные и внешние ключи, модели баз данных, миграции, а также отношения многие-к-одному и многие-ко-многим.

Наконец, потребуется опыт работы с Python и Django.

Настройка проекта

Для создания нового API-проекта для начала создайте виртуальную среду Python в своей рабочей директории. Для этого запустите следующую команду в терминале:

В Windows это будет source env\Scripts\activate .

Не забывайте запускать все команды из этого руководства в виртуальной среде. Убедиться в том, что она активирована можно благодаря надписи ( env ) в начале строки приглашения к вводу в терминале.

Чтобы деактивировать среду, введите deactivate .

После этого установите Django и REST Framework в среду:

Создание нового API-проекта

Вам также понадобится пользователь admin для взаимодействия с панелью управления Django и API. Из терминала запустите следующее:

Установите любой пароль (у него должно быть как минимум 8 символов). Если вы введете слишком простой пароль, то можете получить ошибку.

Для настройки, добавьте rest_framework и api в файл конфигурации (blog/blog/settings.py):

Добавление ApiConfig позволит добавлять параметры конфигурации в приложение. Другие настройки для этого руководства не потребуются.

Наконец, запустите локальный сервер с помощью команды python manage.py runserver .

админ-панель сайта

Создание API для пользователей

Сериализатор для User

REST Framework Django использует сериализаторы, чтобы переводить наборы запросов и экземпляры моделей в JSON-данные. Сериализация также определяет, какие данные вернет API в ответ на запрос клиента.

Пользователи Django создаются из модели User , которая определена в django.contrib.auth . Для создания сериализатора для модели добавьте следующее в blog/api/serializers.py (файл нужно создать):

По примеру импортируйте модель User из Django вместе с набором сериализаторов из REST Framework Django.

Теперь создайте класс UserSerializer , который должен наследоваться от класса ModelSerializer .

Определите модель, которая должна ассоциироваться с сериализатором (model = User). Массив fields определяет, какие поля модели должны быть включены. Например, можно добавлять поля first_name и last_name .

Класс ModelSerializer генерирует поля сериализатора, которые основаны на соответствующих свойствах модели. Это значит, что не нужно вручную указывать все атрибуты для поля сериализации, поскольку они вытягиваются напрямую из модели.

Этот сериализатор также создает простые методы create() и update() . При необходимости их можно переписать.

Ознакомиться подробнее с работой ModelSerializer можно на официальном сайте.

Представления для User

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

REST Framework предоставляет несколько обобщенных представлений, основанных на классе APIView . Они представляют собой самые распространенные паттерны.

Например, ListAPIView используется для эндпоинтов с доступом только для чтения. Он предоставляет метод-обработчик get . ListCreateAPIView используется для эндпоинтов с разрешением чтения-записи, а также обработчики get и post .

Для создания эндпоинта только для чтения, который возвращал бы список пользователей, добавьте следующее в blog/api/views.py:

В первую очередь здесь импортируется generics коллекция представлений, а также модель User и UserSerialized из предыдущего шага. Представление UserList предоставляет доступ только для чтения (через get ) к списку пользователей, а UserDetails — к одному пользователю.

Названия представлений должны быть в следующем формате: List и Details для коллекции объектов и одного объекта соответственно.

Для каждого представления переменная queryset содержит коллекцию экземпляров модели, которую возвращает User.objects.all() . Значением serializer_class должно быть UserSerializer , который и сериализует данные модели User .

Пути к эндпоинтам будут настроены на следующем шаге.

URL-паттерны

С моделью, сериализатором и набором представлений для User финальным шагом будет создание эндпоинтов (которые в Django называются URL-паттернами) для каждого представления.

В первую очередь добавьте следующее в blog/api/urls.py (этот файл тоже нужно создать):

Здесь импортируется функция path и также коллекция представлений приложения api .

Функция path создает элемент, который Django использует для показа страницы приложения. Для этого Django в первую очередь ищет нужный элемент с соответствующим URL (например, users/ ) для запрошенного пользователем. После этого он импортирует и вызывает соответствующее представление (то есть, UserList )

Последовательность <int:pk> указывает на целочисленное значение, которое является основным ключом ( pk ). Django захватывает эту часть URL и отправляет в представление в виде аргумента-ключевого слова.

Прежде чем можно будет взаимодействовать с этими URL-паттернами (и теми, которые будут созданы позже) их нужно добавить в проект. Добавьте следующее в blog/blog/urls.py:

Django REST framework User List

Django REST framework User Detail

В итоге класс модели Django сериализуется с помощью UserSerializaer . Он предоставляет данные представлениям UserList и UserDetail , доступ к которым можно получить с помощью паттернов users/ и users/<int:pk> .

Создание API для Post

После базовой настройки можно приступать к созданию полноценного API для блога с эндпоинтами для постов, комментариев и категорий. Начнем с API для Post.

Модель Post

В blog/api/models.py создайте модель Post , которая наследуется от класса Model из Django и определите ее поля:

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

В этом случае пользователь может иметь много статей, но у поста может быть всего один владелец. Поле owner может быть использовано во фронтенд-приложении для получения пользователя и отображения его имени в качестве автора поста.

Аргумент related_name позволяет задать другое имя доступа к текущей модели ( posts ) вместо стандартного ( post_set ). Список постов будет добавлен в сериализатор User на следующем шаге для завершения отношения многие-к-одному.

Каждый раз при обновлении модели запускайте следующие команды для обновления базы данных:

Поскольку мы работаем с моделями Django, таким как User , посты можно изменить из административной панели Django, зарегистрировав ее в blog/api/admin.py:

Позже их можно будет создавать и через графическое представление API.

Также можно выбрать owner среди существующих пользователей. При создании поста в API пользователя выбирать не нужно. Owner будет задан автоматически на основе данных залогиненного пользователя. Это настроим в следующем шаге.

Сериализатор Post

Чтобы добавить модель Post в API, нужно повторить шаги добавления модели User .

Сначала нужно сериализовать данные модели Post . В blog/api/serializers.py добавьте следующее:

Импортируйте модель Post из приложения api и создайте PostSerializer , который будет наследоваться от класса ModelSerializer . Задайте модель и поля, которые будут использоваться сериализатором.

ReadOnlyField — это класс, возвращающий данные без изменения. В этом случае он используется для возвращения поля username вместо стандартного id .

Дальше добавьте поле posts в UserSerializer . Отношение многие-к-одному между постами и пользователями определено моделью Post в прошлом шаге. Название поля ( posts ) должно быть равным аргументу related_field поля Post.owner . Замените posts на post_set (значение по умолчанию), если вы не задали значение related_field в прошлом шаге.

PrimaryKeyRelatedField представляет список публикаций в этом отношении многие-к-одному ( many=True указывает на то, что постов может быть больше чем один).

Если не задать read_only=True поле posts будет иметь права записи по умолчанию. Это значит, что будет возможность вручную задавать список статей, принадлежащих пользователю при его создании. Вряд ли это желаемое поведение.

Обратите внимание на то, что список posts — это, по сути, список id. Вместо этого можно возвращать список URL с помощью HyperLinkModelSerializer .

Читайте также: