Сериализация
Введение
В этом уроке мы рассмотрим создание простого Web API с подсветкой кода для фрагментов кода. Попутно будут представлены различные компоненты, составляющие DRF, и вы получите полное представление о том, как все это сочетается друг с другом.
Учебник довольно подробный, поэтому перед началом работы вам, вероятно, стоит взять печенье и выпить чашку любимого напитка. Если вам нужен лишь краткий обзор, лучше обратиться к документации quickstart.
Примечание: Код для этого руководства доступен в репозитории encode/rest-framework-tutorial на GitHub. Не стесняйтесь клонировать репозиторий и посмотреть код в действии.
Настройка новой среды
Прежде чем делать что-либо еще, мы создадим новую виртуальную среду, используя venv. Это позволит убедиться, что наша конфигурация пакетов будет изолирована от других проектов, над которыми мы работаем.
Теперь, когда мы находимся в виртуальной среде, мы можем установить наши зависимости.
Примечание: Чтобы выйти из виртуальной среды в любое время, просто введите deactivate
. Для получения дополнительной информации смотрите документацию venv.
Начало работы
Итак, мы готовы приступить к кодированию. Чтобы начать, давайте создадим новый проект для работы.
После этого мы можем создать приложение, которое мы будем использовать для создания простого Web API.
Нам нужно добавить наше новое приложение snippets
и приложение rest_framework
в INSTALLED_APPS
. Давайте отредактируем файл tutorial/settings.py
:
Хорошо, мы готовы к работе.
Создание модели для работы
Для целей этого руководства мы начнем с создания простой модели Snippet
, которая используется для хранения фрагментов кода. Перейдите к редактированию файла snippets/models.py
. Примечание: Хорошая практика программирования включает комментарии. Хотя вы найдете их в нашей версии этого учебного кода в репозитории, здесь мы их опустили, чтобы сосредоточиться на самом коде.
Нам также потребуется создать начальную миграцию для нашей модели сниппетов и впервые синхронизировать базу данных.
Создание класса Serializer
Первое, что нам нужно для начала работы над нашим Web API, это обеспечить способ сериализации и десериализации экземпляров сниппетов в такие форматы, как json
. Мы можем сделать это, объявив сериализаторы, которые работают очень похоже на формы Django. Создайте файл в каталоге snippets
с именем serializers.py
и добавьте следующее.
Первая часть класса сериализатора определяет поля, которые сериализуются/десериализуются. Методы create()
и update()
определяют, как создаются или изменяются полноценные экземпляры при вызове serializer.save()
.
Класс сериализатора очень похож на класс Django Form
и включает аналогичные флаги проверки различных полей, такие как required
, max_length
и default
.
Флаги полей также могут управлять тем, как сериализатор должен отображаться в определенных обстоятельствах, например, при рендеринге в HTML. Флаг {'base_template': 'textarea.html'}
выше эквивалентен использованию widget=widgets.Textarea
в классе Django Form
. Это особенно полезно для управления отображением Web-интерфейса API, как мы увидим далее в учебнике.
Мы также можем сэкономить время, используя класс ModelSerializer
, как мы увидим позже, но пока мы сохраним определение нашего сериализатора явным.
Работа с сериализаторами
Прежде чем двигаться дальше, мы ознакомимся с использованием нашего нового класса Serializer. Давайте зайдем в оболочку Django.
Хорошо, когда мы разобрались с несколькими импортами, давайте создадим пару фрагментов кода для работы.
Теперь у нас есть несколько экземпляров фрагментов, с которыми можно поиграть. Давайте посмотрим на сериализацию одного из этих экземпляров.
На данном этапе мы перевели экземпляр модели в собственные типы данных Python. Для завершения процесса сериализации мы преобразуем данные в json
.
Десериализация аналогична. Сначала мы разбираем поток на собственные типы данных Python...
...затем мы восстанавливаем эти собственные типы данных в полностью заполненный экземпляр объекта.
Обратите внимание, насколько API похож на работу с формами. Сходство должно стать еще более очевидным, когда мы начнем писать представления, использующие наш сериализатор.
Мы также можем сериализовать наборы запросов вместо экземпляров моделей. Для этого мы просто добавим флаг many=True
в аргументы сериализатора.
Использование сериализаторов моделей
Наш класс SnippetSerializer
повторяет много информации, которая также содержится в модели Snippet
. Было бы неплохо, если бы мы могли сделать наш код более лаконичным.
Подобно тому, как Django предоставляет классы Form
и ModelForm
, DRF включает классы Serializer
и ModelSerializer
.
Давайте рассмотрим рефакторинг нашего сериализатора с помощью класса ModelSerializer
. Снова откройте файл snippets/serializers.py
и замените класс SnippetSerializer
на следующий.
Одним из приятных свойств сериализаторов является то, что вы можете просмотреть все поля экземпляра сериализатора, распечатав его представление. Откройте оболочку Django с помощью команды python manage.py shell
, затем попробуйте выполнить следующее:
Важно помнить, что классы ModelSerializer
не делают ничего особенно волшебного, они просто являются синтаксическим сахаром для создания классов сериализаторов:
Автоматически определяемый набор полей.
Простые реализации по умолчанию для методов
create()
иupdate()
.
Написание обычных представлений Django с использованием нашего сериализатора
Давайте посмотрим, как мы можем написать несколько представлений API, используя наш новый класс Serializer. На данный момент мы не будем использовать другие возможности фреймворка REST, мы просто напишем представления как обычные представления Django.
Отредактируйте файл snippets/views.py
и добавьте следующее.
Корнем нашего API будет представление, которое поддерживает вывод списка всех существующих сниппетов или создание нового сниппета.
Обратите внимание, что, поскольку мы хотим иметь возможность делать POST запросы к этому представлению от клиентов, у которых не будет CSRF токена, мы должны пометить представление как csrf_exempt
. Это не то, что вы обычно хотите сделать, и представления DRF на самом деле используют более разумное поведение, чем это, но для наших целей сейчас это подойдет.
Нам также понадобится представление, которое соответствует отдельному фрагменту и может быть использовано для получения, обновления или удаления фрагмента.
Наконец, нам нужно подключить эти представления. Создайте файл snippets/urls.py
:
Нам также нужно настроить корневой urlconf в файле tutorial/urls.py
, чтобы включить в нее URL нашего приложения-фрагмента.
Стоит отметить, что есть несколько крайних случаев, которые мы не обрабатываем должным образом в настоящее время. Если мы отправим неверно сформированный json
, или если запрос будет сделан с методом, который представление не обрабатывает, то мы получим ответ 500 "ошибка сервера". Тем не менее это пока сойдет.
Тестирование нашей первой попытки создания Web API
Теперь мы можем запустить отладочный сервер, который будет обслуживать наши фрагменты.
Выйти из оболочки...
...и запустите сервер разработки Django.
В другом окне терминала мы можем протестировать сервер.
Мы можем протестировать наш API, используя curl или httpie. Httpie - это удобный http-клиент, написанный на Python. Давайте установим его.
Вы можете установить httpie с помощью pip:
Наконец, мы можем получить список всех сниппетов:
Или мы можем получить конкретный фрагмент, обратившись к нему по id:
Аналогично, вы можете получить тот же json, посетив эти URL-адреса в веб-браузере.
Где мы сейчас
Пока что у нас все в порядке, у нас есть API сериализации, который очень похож на Django Forms API, и несколько обычных представлений Django.
Наши представления API на данный момент не делают ничего особенного, кроме как обслуживают json
ответы, и есть несколько крайних случаев обработки ошибок, которые мы хотели бы убрать, но это функционирующий Web API.
В части 2 учебника мы посмотрим, как можно начать улучшать ситуацию.
Last updated