Что такое Rest API и что нужно для настройки базового API с использованием Django REST Framework?

Прямые заметки разработчиков, сделанные на протяжении следующего руководства Dennis IvyDjango 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:

  1. Чтобы создать общедоступный API, с которым может взаимодействовать любое приложение.
  2. Для распространения данных в ваши собственные приложения

Самое приятное то, что 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 будет наследоваться от класса сериализатора модели.

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

  1. model - чтобы указать, какую модель мы будем сериализовать
  2. 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.