Django.fun

Создайте REST API за 30 минут с помощью Django REST Framework

Почему REST API?

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

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

Есть несколько ключевых вариантов запроса REST API:

  • GET — Самый распространенный вариант, возвращает некоторые данные из API в зависимости от конечной точки, которую вы посещаете, и любых предоставленных вами параметров.
  • POST — Создает новую запись, которая добавляется в базу данных
  • PUT — Ищет запись по указанному вами URI. Если она существует, обновляет существующую запись. Если нет, создает новую запись
  • DELETE — Удаляет запись по заданному URI
  • PATCH — Обновляет отдельные поля записи

Обычно API - это окно в базу данных. Бэкэнд API обрабатывает запросы к базе данных и форматирует ответ. Вы получаете статический ответ любого запрошенного вами ресурса, обычно в формате JSON.

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

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

Процесс запроса и преобразования значений табличной базы данных в JSON или другой формат называется сериализацией. При создании API правильная сериализация данных является основной проблемой.

Почему Django REST Framework?

Самая большая причина использовать Django REST Framework заключается в том, что он упрощает сериализацию!

В Django вы определяете свои модели для своей базы данных с помощью Python. Хотя вы можете писать необработанный SQL, по большей части Django ORM обрабатывает все миграции и запросы базы данных.

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

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

Таким образом, Django REST Framework прекрасно работает с Django ORM, который уже выполняет всю тяжелую работу по запросам к базе данных. Всего несколько строк кода с использованием Django REST Framework, и вы можете сериализовать свои модели баз данных в форматы REST-ful.

Список пунктов для создания REST API в Django

Итак, исходя из того, что мы знаем, каковы шаги по созданию REST API?

  1. Настроить Django
  2. Создайте модель в базе данных, которой будет управлять Django ORM.
  3. Настройте Django REST Framework
  4. Сериализуйте модель из шага 2
  5. Создайте конечные точки URI для просмотра сериализованных данных

Если это кажется простым, это потому, что это так. Поехали!

1. Настройка Django

Чтобы создать приложение Django, нам нужно установить Django. Это достаточно просто!

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

Вот видео этих шагов (но с другим названием проекта), если вы визуально обучаетесь: Видеурок "Создание Django приложения"Начинаем Django приложение правильно

1.1 Virtual Environment

Я использую pyenv и pyenv-virtualenv для своих сред:

$ pyenv virtualenv django-rest
Looking in links: /tmp/tmpjizkdypn
Requirement already satisfied: setuptools in /home/bennett/.pyenv/versions/3.6.8/envs/django-rest/lib/python3.6/site-packages (40.6.2)
Requirement already satisfied: pip in /home/bennett/.pyenv/versions/3.6.8/envs/django-rest/lib/python3.6/site-packages (18.1)
$ pyenv local django-rest

1.2 Установка Django

Теперь мы можем установить Django:

$ pip install django

Затем давайте начнем новый проект Django:

$ django-admin startproject mysite

Если мы сейчас посмотрим на каталог, то увидим, что Django создал для нас новую папку:

$ ls
mysite/

И если мы заглянем в эту папку, там есть все, что нам нужно для запуска сайта Django:

$ cd mysite/
$ ls
manage.py* mysite/

Давай убедимся, что это работает. Тестовый запуск сервера Django:

$ python manage.py runserver
Watching for file changes with StatReloader
Performing system checks...
System check identified no issues (0 silenced).
You have 17 unapplied migration(s). Your project may not work properly until you apply the migrations for app(s): admin, auth, contenttypes, sessions.
Run 'python manage.py migrate' to apply them.
May 17, 2019 - 16:09:28
Django version 2.2.1, using settings 'mysite.settings'
Starting development server at http://127.0.0.1:8000/
Quit the server with CONTROL-C.

Перейдите на localhost:8000, и вы должны увидеть экран приветствия Django!

1.3 Создание приложения API

Мы могли бы создать наше приложение со структурой папок, как сейчас. Однако лучше всего разделить проект Django на отдельные приложения, когда вы создаете что-то новое.

Итак, давайте создадим новое приложение для нашего API:

$ python manage.py startapp myapi
$ ls
db.sqlite3  manage.py*  myapi/  mysite/

1.4 Зарегистрируйте приложение myapi в проекте mysite

Нам нужно сказать Django, чтобы он распознал это новое приложение, которое мы только что создали. Шаги, которые мы сделаем позже, не сработают, если Django не знает о myapi.

Итак, редактируем mysite/settings.py:

INSTALLED_APPS = [
    'myapi.apps.MyapiConfig',
    ... # Оставьте все остальные INSTALLED_APPS
]

1.5 Перенести базу данных

Помните, как я сказал, что Django позволяет определять модели баз данных с помощью Python?

Каждый раз, когда мы создаем или вносим изменения в модель, нам нужно указать Django перенести эти изменения в базу данных. Затем Django ORM записывает для нас все команды SQL CREATE TABLE.

Оказывается, Django поставляется с несколькими уже встроенными моделями. Нам нужно перенести эти встроенные модели в нашу базу данных.

(Для тех из вас, кто думает: «Мы не создавали базу данных!». Вы правы. Но Django создаст для нас простую базу данных SQLite, если мы не укажем иное. И SQLite - это круто!)

Итак, давайте перенесем эти исходные модели:

$ python manage.py migrateOperations to perform:
  Apply all migrations: admin, auth, contenttypes, sessions
Running migrations:
  Applying contenttypes.0001_initial... OK
  Applying auth.0001_initial... OK
  Applying admin.0001_initial... OK
  Applying admin.0002_logentry_remove_auto_add... OK
  Applying admin.0003_logentry_add_action_flag_choices... OK
  Applying contenttypes.0002_remove_content_type_name... OK
  Applying auth.0002_alter_permission_name_max_length... OK
  Applying auth.0003_alter_user_email_max_length... OK
  Applying auth.0004_alter_user_username_opts... OK
  Applying auth.0005_alter_user_last_login_null... OK
  Applying auth.0006_require_contenttypes_0002... OK
  Applying auth.0007_alter_validators_add_error_messages... OK
  Applying auth.0008_alter_user_username_max_length... OK
  Applying auth.0009_alter_user_last_name_max_length... OK
  Applying auth.0010_alter_group_name_max_length... OK
  Applying auth.0011_update_proxy_permissions... OK
  Applying sessions.0001_initial... OK

1.6 Создать суперпользователя

Еще одна вещь, прежде чем мы продолжим.

Мы собираемся создать несколько моделей. Было бы неплохо, если бы у нас был доступ к красивому интерфейсу администратора Django, когда мы хотим просматривать данные в нашей базе данных.

Для этого нам потребуются учетные данные для входа. Итак, давайте сделаем себя владельцами и администраторами этого проекта. ВСЕМОГУЩЕГО СУПЕРПОЛЬЗОВАТЕЛЯ!!!

$ python manage.py createsuperuser
Username (leave blank to use 'user'): 
Email address: user@example.com
Password: 
Password (again): 
Superuser created successfully.

Убедимся, что это работает. Запустите сервер Django:

$ python manage.py runserver

А затем перейдите на localhost:8000/admin

Войдите в систему со своими учетными данными суперпользователя, и вы должны увидеть панель администратора:

2. Создайте модель в базе данных, которой будет управлять Django ORM.

Сделаем нашу первую модель!

Мы создадим её в myapi/models.py, поэтому откройте этот файл.

2.1 myapi/models.py

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

# models.py
from django.db import models

class Hero(models.Model):
    name = models.CharField(max_length=60)
    alias = models.CharField(max_length=60)

    def __str__(self):
        return self.name

name и alias - это символьные поля, в которых мы можем хранить строки. Метод __str__ просто сообщает Django, что печатать, когда ему нужно распечатать экземпляр модели Hero.

2.2 Сделайте миграции

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

$ python manage.py makemigrations
Migrations for 'myapi':
  myapi/migrations/0001_initial.py
    - Create model Hero
$ python manage.py migrate
Operations to perform:
  Apply all migrations: admin, auth, contenttypes, myapi, sessions
Running migrations:
  Applying myapi.0001_initial... OK

2.3 Зарегистрируйте Hero на сайте администратора

Помните тот замечательный админский сайт, который поставляется прямо из коробки с Django?

Он не знает о существовании модели Hero, но с помощью двух строк кода мы можем сказать это о Hero.

Откройте myapi/admin.py и сделайте так:

from django.contrib import admin
from .models import Hero

admin.site.register(Hero)

Теперь запустим сервер Django:

$ python manage.py runserver

Зайдите на localhost:8000/admin/.

2.4 Создайте новых героев

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

Нажмите «Добавить» и создайте своих героев!

3. Настройте Django REST Framework.

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

Для этого нам понадобится Django REST Framework, так что давайте установим его.

$ pip install djangorestframework

Теперь скажите Django, что мы установили REST Framework в mysite/settings.py:

INSTALLED_APPS = [
    # Все установленные вами приложения останутся прежними
    ...
    'rest_framework',
]

Вот и все!

4. Сериализация модели героя

Теперь мы начинаем открывать новые горизонты. Нам нужно сообщить REST Framework о нашей модели Hero и о том, как она должна сериализовать данные.

Помните, сериализация - это процесс преобразования модели в JSON. Используя сериализатор, мы можем указать, какие поля должны присутствовать в JSON-представлении модели.

Сериализатор превратит наших героев в представление JSON, чтобы пользователь API мог их анализировать, даже если они не используют Python. В свою очередь, когда пользователь отправляет данные JSON в наш API, сериализатор преобразует этот JSON в модель Hero, чтобы мы могли сохранить или проверить.

Для этого создадим новый файл - myapi/serializers.py.

В этом файле нам необходимо:

  1. Импортировать модель Hero
  2. Импортировать сериализатор REST Framework
  3. Создать новый класс, который связывает Hero с его сериализатором

Вот как:

# serializers.py
from rest_framework import serializers

from .models import Hero

class HeroSerializer(serializers.HyperlinkedModelSerializer):
    class Meta:
        model = Hero
        fields = ('name', 'alias')

5. Отображение данных

Теперь все, что осталось сделать, это подключить URL-адреса и представления для отображения данных!

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

Начнем с представления. Нам нужно отрендерить разных героев в формате JSON.

Для этого нам необходимо:

  1. Запросить базу данных для всех героев
  2. Передать этот набор запросов к базе данных в только что созданный сериализатор, чтобы он был преобразован в JSON и отображен.

В myapi/views.py:

# views.py
from rest_framework import viewsets

from .serializers import HeroSerializer
from .models import Hero

class HeroViewSet(viewsets.ModelViewSet):
    queryset = Hero.objects.all().order_by('name')
    serializer_class = HeroSerializer

ModelViewSet - это специальное представление, которое предоставляет Django Rest Framework. Он будет обрабатывать GET и POST для Heroe без дополнительной работы.

5.2 URL-адреса

Ладно, круто. Мы так близки. Последний шаг - указать URL-адрес только что созданной области просмотра.

В Django URL-адреса сначала разрешаются на уровне проекта. Итак, в каталоге mysite/ есть файл с именем urls.py.

Вы увидите, что URL-адрес сайта администратора уже присутствует. Теперь нам просто нужно добавить URL-адрес для нашего API. А пока давайте просто поместим наш API в индекс:

# mysite/urls.py
from django.contrib import admin
from django.urls import path, include

urlpatterns = [
    path('admin/', admin.site.urls),
    path('', include('myapi.urls')),
 ]

5.3 URL для API

Если вы обращаете внимание, а не просто копируете вслепую, вы заметите, что мы включили myapi.urls. Это путь к файлу, который мы еще не редактировали. И именно здесь Django будет искать инструкции по маршрутизации этого URL.

Итак, поехали дальше - myapi/urls.py:

# myapi/urls.py
from django.urls import include, path
from rest_framework import routers
from . import views

router = routers.DefaultRouter()
router.register(r'heroes', views.HeroViewSet)

# Wire up our API using automatic URL routing.
# Additionally, we include login URLs for the browsable API.
urlpatterns = [
    path('', include(router.urls)),
    path('api-auth/', include('rest_framework.urls', namespace='rest_framework'))
]

Обратите внимание, что мы добавили кое-что под названием router, которое мы импортировали из rest_framework.

Маршрутизатор REST Framework будет следить за тем, чтобы наши запросы динамически попадали в нужный ресурс. Если мы добавим или удалим элементы из базы данных, URL-адреса обновятся, чтобы соответствовать. Круто, правда?

Маршрутизатор работает с viewset (смотрите views.py выше) для динамической маршрутизации запросов. Для того, чтобы маршрутизатор работал, он должен указывать на viewset, и в большинстве случаев, если у вас есть viewset, вы захотите, чтобы маршрутизатор работал с ним.

Пока что мы добавили в маршрутизатор только одну модель + сериализатор + набор просмотра - Heroes. Но мы можем добавить больше в будущем, повторяя тот же процесс, описанный выше, для разных моделей! (Может быть, в следующий раз создадим Villains API?)

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

path('path/to/my/view/', MySimpleView.as_view())

Проверьте!

Снова запустите сервер Django:

$ python manage.py runserver

Теперь перейдите на localhost:8000

Посетите конечную точку через GET

Если мы нажмем ссылку (гиперссылки - хороший REST-ful дизайн, кстати), мы увидим результаты API героев:

GET для индивидуального героя

Мы можем запросить с помощью GET единственный экземпляр модели, используя его ID.

viewsets представлений Django REST Framework позаботятся об этом за нас.

Если вы перейдете на 127.0.0.1:8000/heroes/<id>/, где <id> - идентификатор одной из ваших моделей Героев, вы сможете увидеть только этого героя.

Например, http://127.0.0.1:8000/heroes/1/ для меня возвращает:

GET /heroes/1/HTTP 200 OK
Allow: GET, PUT, PATCH, DELETE, HEAD, OPTIONS
Content-Type: application/json
Vary: Accept{
    "name": "Batman",
    "alias": "Bruce Wayne"
}

Мы можем сделать это немного более удобным, добавив ID в ответ heroes/. В myapi/serializers.py измените список полей, включив «id»:

class HeroSerializer(serializers.HyperlinkedModelSerializer):
    class Meta:
        model = Hero
        fields = (‘id’, ‘name’, ‘alias’)

Теперь список героев выглядит так:

GET /heroes/HTTP 200 OK
Allow: GET, POST, HEAD, OPTIONS
Content-Type: application/json
Vary: Accept[
    {
        "id": 1,
        "name": "Batman",
        "alias": "Bruce Wayne"
    },
    {
        "id": 2,
        "name": "Superman",
        "alias": "Clark Kent"
    },
    {
        "id": 3,
        "name": "Wonder Woman",
        "alias": "Diana Prince"
    }
]

Мы можем использовать эти идентификаторы для поиска отдельных моделей.

Отправить запрос POST

Наш API также обрабатывает POST запросы. Мы можем отправить JSON в API, и он создаст новую запись в базе данных.

Теперь в нашем API есть Капитан Америка!

Быстрые API REST с Django REST Framework

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

Тем не менее, вы хорошо продвигаетесь с этим постом. REST Framework довольно хорошо справляется со сложностью. Если вы застряли, есть отличное сообщество, готовое помочь вам найти решение.

Удачи, создавая новые API!

Перевод https://medium.com/swlh/build-your-first-rest-api-with-django-rest-framework-e394e39a482c

Поделитесь с другими: