Что такое Rest API и что нужно для настройки базового API с использованием Django REST Framework?
Прямые заметки разработчиков, сделанные на протяжении следующего руководства Dennis Ivy — Django REST Framework Oversimplified
В этом посте мы рассмотрим, что такое REST API и что нужно для настройки базового API с использованием Django REST Framework.
Вы также можете следить за моим репозиторием на Github:
Что такое Django REST Framework?
Предполагая, что вы знакомы с Django как с фреймворком на основе Python для создания веб-приложений, Django REST Framework эффективно помогает нам создавать API с Django.
Проще говоря, API — это набор функций и протоколов, позволяющих приложениям взаимодействовать друг с другом. Будь то извлечение данных из источника для переноса в ваше приложение или выполнение функции, которая что-то делает со сторонним приложением.
Две веские причины для создания API с помощью Django REST Framework:
- Чтобы создать общедоступный API, с которым может взаимодействовать любое приложение.
- Для распространения данных в ваши собственные приложения
Самое приятное то, что API может работать как «сервер-сервер», так и «сервер-интерфейс» — практически с любым технологическим стеком!
Установить Джанго
Начнем с создания проекта с нуля. Я настоятельно рекомендую использовать виртуальную среду и установить Django внутри нее. Вы можете следовать этому руководству, которое я написал некоторое время назад, чтобы начать.
Отсюда мы будем делать все в виртуальной среде.
Чтобы установить Django, выполните следующую команду
pip install django
Создать проект Джанго
Установив Django, давайте создадим новый проект с именем «drf_simple», используя следующую команду.
django-admin startproject drf_simple
Это создаст следующие файлы:
drf_simple
├── drf_simple
│ ├── __init__.py
│ ├── asgi.py
│ ├── settings.py
│ ├── urls.py
│ └── wsgi.py
└── manage.py
Установите Django REST Framework
Когда наши шаблонные файлы готовы к работе, давайте установим пакет Django REST Framework с помощью следующей команды.
pip install djangorestframework
Как и любое приложение Django, нам нужно установить его в пределах settings.py
.
# drf_simple > settings.py
INSTALLED_APPS = [ ... 'rest_framework', ]
Настройка API
Хотя существует несколько способов создания API с помощью Django, Деннис предпочитает создавать отдельный модуль Python, а не настраивать приложение Django.
Это также означает, что нам не нужно будет устанавливать наш API как приложение Django.
Для API нам нужно создать новую папку в корне нашего проекта и назвать ее «API». Поскольку мы хотим сослаться на этот модуль API в нашем проекте Django, нам нужно включить пустой файл __init__.py
.
В этой папке мы также хотим создать несколько представлений и URL-адресов, которые будут работать так же, как и любое приложение Django.
drf_simple
├── api // new folder
│ ├── __init__.py // new file
│ └── views.py // new file
├── drf_simple
│ ├── __init__.py
│ ├── asgi.py
│ ├── settings.py
│ ├── urls.py
│ └── wsgi.py
└── manage.py
В views.py
давайте сначала импортируем класс Response
из Django REST Framework. Этот объект Response
принимает данные Python, которые были сериализованы, и отображает их как данные JSON.
Кроме того, поскольку мы работаем с представлениями на основе функций, нам также потребуется импортировать декоратор представлений API из Django REST Framework.
# api > views.py
from rest_framework.response import Response from rest_framework.decorators import api_view
getData
Просмотр
Давайте создадим нашу первую конечную точку getData
, которая будет использоваться для извлечения данных из нашей базы данных. Используя декоратор api_view
, который мы импортировали из Django REST Framework, мы можем передать метод GET
в список разрешенных методов.
Мы можем добавить в декоратор дополнительные методы, такие как POST, PUT и DELETE, но поскольку мы возвращаем только данные, нам нужно будет использовать только метод GET.
А пока давайте вернем объект Response
со словарем Python в качестве фиктивных данных.
# api > views.py
from rest_framework.response import Response from rest_framework.decorators import api_view
@api_view(['GET']) def getData(request): person = {'name':'Dennis', 'age':28} return Response(person)
getData
Конечная точка
Когда наше представление готово к работе, давайте назначим его конечной точке. Для этого давайте создадим файл urls.py
в папке нашего API.
drf_simple
├── api
│ ├── __init__.py
│ ├── views.py
│ └── urls.py // new file
├── drf_simple
│ ├── __init__.py
│ ├── asgi.py
│ ├── settings.py
│ ├── urls.py
│ └── wsgi.py
└── manage.py
Подобно файлу urls.py
приложения Django, мы можем импортировать объект path
из Django, а также представление, которое мы только что создали, и назначить представление шаблону URL.
# api > urls.py
from django.urls import path from . import views
urlpatterns = [ path('', views.getData) ]
Подключить конечную точку
Чтобы получить доступ к нашей недавно созданной конечной точке, нам нужно подключить наш urls.py
из папки API к нашему корневому файлу urls.py
нашего проекта.
# drf_simple > urls.py
from django.contrib import admin from django.urls import path, include
urlpatterns = [ path('admin/', admin.site.urls), path('', include('api.urls')), ]
Запустить сервер
Настроив наш первый маршрут API, давайте проверим его работу, запустив сервер с помощью следующей команды:
python manage.py runserver
Вы увидите ошибку о непримененных миграциях — это относится к нашей базе данных, к которой мы вернемся позже в этом руководстве.
Затем перейдите в браузере на http://localhost:8000/
Теперь мы можем видеть наши фиктивные данные в нашем API.
Просмотр нашего API
Одной из замечательных особенностей использования Django REST Framework является пользовательский интерфейс, который помогает нам читать и понимать, что происходит в нашем API.
Данные также можно отобразить как необработанные, щелкнув раскрывающееся меню в правом верхнем углу и выбрав JSON.
Это эффективно добавит к URL-адресу запрос в формате JSON, что обычно наблюдается при запросе API.
http://localhost:8000/?format=json
Настройка базы данных
До сих пор мы могли настроить Django REST Framework для рендеринга некоторых фиктивных данных. Теперь было бы здорово подключить его к нашей базе данных. Для этого нам нужно создать модели, а также перенести нашу базу данных, что должно быть вам знакомо, если вы ранее создавали приложения Django.
Но вместо того, чтобы возвращать пользователю объекты python через Django ORM, мы будем сериализовать данные, возвращаемые из базы данных, в объект JSON, чтобы любое приложение могло подключиться к нашим данным.
Итак, чтобы создать нашу модель, мы создадим новое приложение Django под названием «база».
python manage.py startapp base
Это создаст следующую папку и файлы:
drf_simple
├── api
│ ├── __init__.py
│ ├── views.py
│ └── urls.py
├── base // new Django app
│ ├── migrations
│ ├── __init__.py
│ ├── admin.py
│ ├── apps.py
│ ├── models.py
│ ├── tests.py
│ └── views.py
├── drf_simple
│ ├── __init__.py
│ ├── asgi.py
│ ├── settings.py
│ ├── urls.py
│ └── wsgi.py
└── manage.py
Как и любое создаваемое приложение Django, оно должно быть зарегистрировано в settings.py
.
# drf_simple > settings.py
INSTALLED_APPS = [ ... 'base', ]
Установив наше приложение, мы можем перейти к models.py
и создать новую модель с именем Item
. Модель будет состоять только из двух атрибутов:
name
- строковое значениеcreated
- хранит метку времени созданияItem
# base > models.py
from django.db import models
class Item(models.Model): name = models.CharField(max_length=200) created = models.DateTimeField(auto_now_add=True)
Сделать миграции
Создав нашу модель, мы можем выполнять миграции и применять эти миграции к нашей базе данных, используя следующие команды соответственно.
Это также должно удалить предупреждение о непримененных миграциях, которое было у нас ранее, когда мы запускали сервер.
python manage.py makemigrations
python manage.py migrate
Создание записей с помощью Django Shell
Django поставляется со своей собственной командой оболочки, с помощью которой мы можем взаимодействовать с базой данных через ORM Django в терминале.
Чтобы открыть оболочку, мы можем запустить следующее:
python manage.py shell
Отсюда мы импортируем модель Item
из приложения base
. Затем, чтобы создать элемент в нашей базе данных, мы воспользуемся методом create
и назначим атрибут name
(поскольку атрибут created
генерируется автоматически).
# Django shell
from base.models import Item
Item.objects.create(name="Item #1")
Item.objects.create(name="Item #2")
Item.objects.create(name="Item #3")
Чтобы убедиться, что эти элементы были созданы в нашей базе данных, давайте обратимся к этим элементам и распечатаем их внутри нашей оболочки.
# Django shell
items = Item.objects.all()
print(items)
Чтобы выйти из оболочки, выполните следующую команду:
# Django shell
exit()
Сериализировать наши модели
Когда наш сервер снова заработает, давайте вернемся к нашему API и создадим новый файл с именем serializers.py
.
drf_simple
├── api
│ ├── __init__.py
│ ├── views.py
│ ├── urls.py
│ └── serializers.py // new file
├── base
│ ├── migrations
│ ├── __init__.py
│ ├── admin.py
│ ├── apps.py
│ ├── models.py
│ ├── tests.py
│ └── views.py
├── drf_simple
│ ├── __init__.py
│ ├── asgi.py
│ ├── settings.py
│ ├── urls.py
│ └── wsgi.py
└── manage.py
Именно здесь мы создаем сериализаторы наших моделей и настраиваем, как мы хотим, чтобы данные были структурированы, прежде чем они будут возвращены пользователю через объект Response
.
Для начала мы импортируем serializers
из Django REST Framework, а также модель Item
из приложения base
.
# api > serializers.py
from rest_framework import serializers from base.models import Item
Теперь мы можем создать наш класс сериализатора. Как правило, Деннис следует соглашению об именовании имени модели и слова «Сериализатор». Наш ItemSerializer
будет наследоваться от класса сериализатора модели.
Затем мы установим внутренний метакласс, куда мы включим два обязательных атрибута:
model
- чтобы указать, какую модель мы будем сериализоватьfields
— поля модели, которые мы хотим вернуть. Мы можем предоставить либо список атрибутов, либо все, что доступно через значение__all__
# api > serializers.py
class ItemSerializer(serializers.ModelSerializer): class Meta: model = Item fields = '__all__'
Возврат сериализованных данных
Когда наш сериализатор моделей готов к работе, мы можем переключиться на наше представление API и импортировать только что созданные модели Item
и ItemSerializer
.
# api > views.py
from rest_framework.response import Response from rest_framework.decorators import api_view
from base.models import Item from . serializers import ItemSerializer
Далее мы обновим наше представление getData
, заменив наши фиктивные данные запросом к базе данных, чтобы получить все записи Item
. Затем, чтобы иметь возможность отправить запрошенные данные обратно пользователю, их необходимо сериализовать и сохранить внутри объекта Response
.
Обратите внимание, что мы включили атрибут many
и установили для него значение True
. Это значение просто сообщает сериализатору, что мы собираемся сериализовать несколько элементов (массив объектов) одновременно.
Затем в нашем объекте Response
мы хотим специально вернуть сериализованные данные (вместо определения объекта сериализатора).
# api > views.py
from rest_framework.response import Response from rest_framework.decorators import api_view
from base.models import Item from . serializers import ItemSerializer
@api_view(['GET']) def getData(request): items = Item.objects.all() serializer = ItemSerializer(items, many=True) return Response(serializer.data)
Убедившись, что наш сервер работает, вернитесь в браузер, чтобы убедиться, что все наши элементы, хранящиеся в базе данных, теперь находятся в нашем API в виде данных JSON.
addItem
Конечная точка
На данный момент мы создали только одну конечную точку, которая извлекает данные из базы данных. Было бы неплохо добавить еще одну конечную точку, используемую для добавления данных через наш API.
В нашем файле views.py
мы создадим еще одну конечную точку с именем addItem
. Обязательно используйте декоратор api_view
и установите POST в качестве одного из списков методов, которым разрешено взаимодействовать с этой конечной точкой.
Существует множество способов обработки этой конечной точки, но метод, которым мы будем следовать, заключается в простом использовании класса ItemSerializer
и передаче в него данных. Это будет означать, что сериализатор не только создает Item
, но и проверяет данные, поступающие с помощью метода is_valid()
.
Примечание: чтобы получить данные от пользователя в запросе, просто вызовите request.data
Если сериализованные данные, отправленные пользователем, действительны, объект создается в базе данных, и в качестве ответа возвращается новый элемент.
# api > views.py
@api_view(['POST']) def addItem(request): serializer = ItemSerializer(data=request.data) if serializer.is_valid(): serializer.save() return Response(serializer.data)
Последнее, что нам нужно сделать, это назначить новый URL-адрес для этой конечной точки и передать только что созданное представление.
# api > urls.py
from django.urls import path from . import views
urlpatterns = [ path('', views.getData), path('add/', views.addItem), ]
POST-данные через API
Создав конечную точку POST, мы можем вернуться в браузер по следующему маршруту:
http://localhost:8000/add
Вы заметите, что есть интерфейс, сообщающий нам, что метод GET не разрешен. Но когда мы прокручиваем вниз, у нас есть интерфейс, предоставляемый Django REST Framework для отправки некоторых данных с помощью метода POST.
В текстовую область мы будем вводить некоторые данные, которые хотим отправить на конечную точку addItem
. Итак, давайте воспроизведем, как может выглядеть этот запрос из внешнего интерфейса.
Как и в оболочке Django, нам нужно только предоставить атрибут name
, но на этот раз он будет записан внутри объекта JSON. Идите вперед и установите значение в строку и нажмите кнопку POST, чтобы сделать запрос.
{
"name": "Item Created"
}
С отправленными данными мы получаем объект ответа с вновь созданным элементом. Это говорит о том, что мы успешно создали запись в нашей базе данных.
Перенаправив браузер на конечную точку getData
, давайте проверим, попал ли новый Item.
http://localhost:8000/
И вот оно. Спасибо за чтение.
Дополнительные материалы на PlainEnglish.io. Подпишитесь на нашу бесплатную еженедельную рассылку новостей. Подпишитесь на нас в Twitter и LinkedIn. Присоединяйтесь к нашему сообществу Discord.