Файлы
posts
migrations
__init__.py
0001_initial.py
models.py
serializers.py
__init__.py
apps.py
admin.py
tests.py
urls.py
views.py
yatube_api
asgi.py
__init__.py
settings.py
urls.py
wsgi.py
manage.py
views.py
Урок 3: View-функции API
2 / 3
Напишите view-функцию API api_posts_detail, которая обрабатывает методы GET, PUT, PATCH и DELETE и работает только с одним объектом модели Post.
В файл urls.py добавьте эндпоинт api/v1/posts/<int:id>/, который вызывает view-функцию API api_posts_detail. Не забудьте её импортировать.
Для удаления объекта используйте метод .delete(), остальное вы уже делали.
Браузер894x893
Браузер894x893

View-функции API

Запрос к API проходит такой путь:
urls.py — здесь настраивается маршрутизация API, описываются эндпоинты для ресурсов; Эндпоинтами в терминах REST API принято называть URL-адрес, идентифицирующий ресурс.
serializers.py — здесь данные преобразуются в JSON и обратно;
views.py — здесь идёт обработка параметров запроса, получение или запись данных, создание ответа.
Как и всегда в Django, в работе с API применяются Views: функции или классы. Классы могут быть низкого уровня (их пишут вручную) или «высокоуровневые»: в них заготовлены инструменты для решения типовых задач. Основная идея в том, что для решения экзотических задач применяют низкоуровневые классы, а если задача типичная (скажем, CRUD) — высокоуровневые.
Есть ещё так называемые мета-функции, или вьюсеты. Это очень мощный инструмент, ему будет посвящена отдельная тема нашего курса.

Token Authentication

Один из принципов построения REST — отсутствие состояния (stateless). Это значит, что каждый запрос к серверу должен содержать информацию о том, кто совершает этот запрос (информацию о пользователе). Сопоставление этих данных с учетными данными на сервере называется аутентификацией.
Рассмотрим самый простой способ аутентификации — по токену.
Для получения токена клиент посылает серверу запрос, передав логин и пароль. Если в базе данных существует такой пользователь и пароль совпадает, то в ответ клиент получает токен. При каждом последующем запросе к API проводится проверка: есть ли переданный с запросом токен в базе и какому пользователю он соответствует.
Для реализации этого механизма нужно выполнить несколько действий.
  1. Добавить приложение 'rest_framework.authtoken' в INSTALLED_APPS
  2. В settings.py объявить новый способ аутентификации TokenAuthentication и, одновременно, запретить доступ всем неаутентифицированным пользователям, установив значение IsAuthenticated для ключа DEFAULT_PERMISSION_CLASSES:
Скопировать кодPYTHON
REST_FRAMEWORK = { 'DEFAULT_PERMISSION_CLASSES': [ 'rest_framework.permissions.IsAuthenticated', ], 'DEFAULT_AUTHENTICATION_CLASSES': [ 'rest_framework.authentication.TokenAuthentication', ] }
Ограничение доступа настраивается с помощью пермишенов (англ. "permissions", разрешения). Мы поговорим о них подробно в следующем спринте, а пока просто подключите их к проекту.
  1. Выполнить миграции, чтобы в базе данных создались поля для работы и хранения токена: python manage.py migrate
  2. Добавить маршрут для получения токена:
Скопировать кодPYTHON
from rest_framework.authtoken import views urlpatterns += [ path('api-token-auth/', views.obtain_auth_token) ]
В этом уроке вы будете работать в тренажере, поэтому миграции мы выполнили за вас.
Теперь можно отправить POST-запрос к адресу api-token-auth/, передать в теле запроса поля username и password — и в ответ придёт заветный токен:
{ "token": "d31754b63d74f15b48aa91ac387f5115d0ba83d6" }
Этот токен надо будет передавать в заголовке каждого запроса, в поле Authorization: Authorization: Token d31754b63d74f15b48aa91ac387f5115d0ba83d6
При успешной аутентификации TokenAuthentication вернёт такие данные:
  • request.user будет экземпляром пользователя.
  • request.auth будет токеном (экземпляром rest_framework.authtoken.models.Token)
В ответ на неаутентифицированные запросы клиент получит отказ: ему в ответ придёт статус-код HTTP 401 Unauthorized:
{ "detail": "Authentication credentials were not provided." }

View-функции

Чтобы создать view-функцию для API, нужно декорировать обычную view-функцию следующим образом: @api_view(<разрешенные HTTP-методы>) . Такая функция должна возвращать объект Response(<отправляемые данные>).
Рассмотрим пример. View-функция hello при GET-запросе возвращает ответ «Привет, мир!» в формате JSON. При POST-запросе она вернёт строку со включением полученных данных, если они были. При запросах другого типа, например, PUT, вернётся сообщение «Метод не разрешен» и статус-код ошибки "405 Method Not Allowed".
Скопировать кодPYTHON
from rest_framework.decorators import api_view from rest_framework.response import Response @api_view(['GET', 'POST']) def hello(request): if request.method == 'POST': return Response({'message': f'Привет {request.data}'}) return Response({'message': 'Привет, мир!'})
Обычно в API создание нового объекта и запрос всех объектов реализуется в одной функции, а получение/изменение/удаление объекта — в другой. То есть весь функционал CRUD может быть реализован двумя view-функциями API.
Для удобства работы и отладки у DRF есть специальный браузерный API. Он позволяет совершать все виды запросов прямо из браузера, красиво и структурированно выводит объекты, поддерживает авторизацию. Используйте его для проверки работоспособности ваших эндпоинтов.
image
Существуют также другие мощные инструменты для удобной работы и тестирования API. Например, консольный HTTPie и графический Postman. Потестируйте их, эти сервисы помогут вам в разработке.
Пришло время самостоятельно реализовать CRUD на Django REST Framework с помощью view-функций API.
Работайте с сериализатором так же, как с уже знакомыми вам формами. Вспомните методы is_valid(), save(), и delete() — и у вас всё получится!
Прежде чем вы отправитесь в бой, отметим ещё несколько важных моментов:
  • View-функция обрабатывает только те запросы, которые вы указали в декораторе @api_view(<разрешенные HTTP-методы>)
  • Данные приходят в объекте request.data и передаются в конструктор сериализатора через именованный параметр data.
  • Необходимо вернуть клиенту правильный статус-код. Список кодов можно уточнить здесь.
Переименовать
Удалить файл
Переименовать
Удалить файл
Переименовать
Новый файл
Новая папка
Удалить папку
Переименовать
Удалить файл
Переименовать
Удалить файл
Переименовать
Удалить файл
Переименовать
Удалить файл
Переименовать
Удалить файл
Переименовать
Удалить файл
Переименовать
Удалить файл
Переименовать
Удалить файл
Переименовать
Новый файл
Новая папка
Удалить папку
Переименовать
Удалить файл
Переименовать
Удалить файл
Переименовать
Удалить файл
Переименовать
Удалить файл
Переименовать
Удалить файл
Переименовать
Новый файл
Новая папка
Удалить папку
Переименовать
Удалить файл
Новый файл
Новая папка