Здравствуйте друзья, в этой статье мы рассмотрим реализацию swagger UI с использованием функциональных представлений в django rest framework (drf).
Я решил написать статью об этом, потому что недавно я столкнулся с различными проблемами при попытке добавить базовый функционал swagger UI в мой API, я использовал представления на основе функций вместо более популярного подхода на основе классов.
В этой статье мы создадим базовый API продукта с CRUD-приложениями, используя представления на основе функций, а затем добавим swagger UI, чтобы сделать наш API более презентабельным.
- Настройка среды разработки
- Создание наших моделей
- Создание наших сериализаторов
- Создание представления продукта
- Прочитать представление продукта
- Обновить представление продукта
- Удалить представление продукта
- Урлы представления продукта
- Реализация Swagger
- Чтение представления продукта
- Обновить представление продукта
- Удалить представление продукта
Настройка среды разработки
Нам нужно создать наш проект django, но для этого нам нужно настроить среду разработки.
Для начала создайте рабочий каталог и в нем создайте виртуальную среду, используя:
mkdir django-swagger
cd django-swagger
virtualenv env
Далее нам нужно активировать нашу виртуальную среду, используйте соответствующий код, который подходит для вашей ОС, используя любой из приведенных ниже кодов:
Windows --> envScriptsactivate
Linux --> source env/bin/activate
Теперь мы установим наши зависимости, используя:
pip install django djangorestframework
Далее мы запускаем наш проект django, а затем создаем приложение, используя:
django-admin startproject main .
python manage.py startapp prodcuts
Создание наших моделей
Мы успешно создали нашу среду разработки, теперь нам нужно создать модель(и), с которой мы будем работать. Нам нужна простая модель Product
с несколькими полями. Добавьте ее в ваш файл models.py
.
class Product(models.Model):
title = models.CharField(max_length=224)
description = models.CharField(max_length=255)
def __str__(self):
return self.title
Создание наших сериализаторов
Теперь запустим команду makemigrations
, чтобы заполнить нашу базу данных таблицей Product
.
Затем мы создаем файл serializers.py
в нашем product
и добавляем следующий код.
from rest_framework import seriailizers
from .models import Product
class ProductSerializer(serializers.ModelSerializer):
class Meta:
model = Product
fields = "__all__"
class UpdateProductSerializer(serializers.ModelSerializer):
class Meta:
model = Product
fields = ["title", "description"]
def update(self, instance, validated_data):
instance.title = validated_data.get("title", instance.title)
instance.description = validated_data.get("description", instance.description)
Теперь у нас есть готовые модели и сериализаторы. Теперь нам нужно создать представления CRUD
в нашем файле views,py
. Добавьте этот блок кода в ваш файл views.py
.
Создание представления продукта
from rest_framework.response import Response
from rest_framework.decorators import api_view
from rest_framework import status
from .models import Product
from .serializers import ProductSerializer
@api_view(['POST'])
def create_product(request):
if request.method == 'POST':
create_product = ProductSerializer(data=request.data)
if create_product.is_valid():
title = create_product.validated_data.get('title')
description = create_product.validated_data.get('description')
product = Product.objects.create(title=title, description=description)
product.save()
return Response(create_product.data, status=status.HTTP_201_CREATED)
else:
return Response(create_product.errors, status=status.HTTP_400_BAD_REQUEST)
else:
return Response({"Error": "Invalid request type"}, status=status.HTTP_400_BAD_REQUEST)
Прочитать представление продукта
@api_view(['GET'])
def read_product(request):
if request.method == 'GET':
all_products = Product.objects.all()
serialized_products = ProductSerializer(all_products, many=True)
return Response(serialized_products.data, status=status.HTTP_200_OK)
else:
return Response(serialized_products.errors, status=status.HTTP_400_BAD_REQUEST)
Обновить представление продукта
@pi_view(['PATCH'])
def update_product(request, id):
if request.method == 'PATCH':
try:
product = Product.objects.get(id=id)
update_seriailizer = UpdateProductSerializer(product, data=request.data, partial=True)
if update_serializer.is_valid():
update_serializer.save()
return Response({"Message": "Product updated"}, status=status.HTTP_200_OK)
else:
return Response(update_serializer.errors, status=status.HTTP_400_BAD_REQUEST)
except Exception as e:
return Response({"Error": f"Unexpected error {e} occurred.", status=status.HTTP_400_BAD_REQUEST)
else:
return Response({"Error": "Invalid request type", status=status.HTTP_400_BAD_REQUEST})
Удалить представление продукта
@api_view(['POST'])
def delete_view(request):
if request.method == 'POST':
all_products = Product.objects.all()
all_product.delete()
return Response({"Message": "All Products have been deleted"}, status=status.HTTP_200_OK)
else:
return Response({"Error": "Invalid request type"}, status=status.HTTP_400_BAD_REQUEST)
Урлы представления продукта
Теперь нам нужно создать урлы, которые помогут нам получить доступ к конечным точкам. В каталоге product
нам нужно создать файл urls.py
и заполнить его следующим кодом:
from django.urls import path
from . import views
urlpatterns = [
path('create', views.create_product, name='create-product'),
path('read', views.read_product, name='read-all-products'),
path('update/<int:id>', views.update_product, name='update-products'),
path('delete', views.delete_view, name='delete-product')
]
Далее нам нужно добавить нашу конфигурацию url в корневой каталог urls.py
, добавив ее в существующий список urlpatterns
:
path('product/', include('product.urls'))
Также не забудьте импортировать include
вместе с path
из django.urls
.
Реализация Swagger
Мы закончили с созданием API наших продуктов, теперь мы посмотрим, как использовать swagger UI с нашим API, который мы создали. Для начала нам нужно установить пакет drf_yasg
, который поможет нам в реализации swagger UI. yasg
расшифровывается как Yet Another Swagger Generator
.
Чтобы установить его, давайте откроем терминал и введем эту команду:
pip install drf_yasg
После установки добавьте его в список установленных приложений следующим образом:
INSTALLED_APPS = [
'drf_yasg',
]
Мы добавили пакет в установленные приложения, теперь, чтобы увидеть, как происходит волшебство, нам нужно добавить несколько маршрутов в наш корневой файл urls.py
.
Добавьте этот блок кода в корневой файл urls.py
, прямо под импортом django.urls
:
from rest_framework import permissions
from drf_yasg.views import get_schema_view
from drf_yasg import openapi
schema_view = get_schema_view(
openapi.Info(
title="Products API",
default_version='v1',
description="Description",
terms_of_service="https://www.google.com/policies/terms/",
contact=openapi.Contact(email="<your-gmail>@gmail.com"),
license=openapi.License(name="BSD License"),
),
public=True,
permission_classes=[permissions.AllowAny],
)
Этот блок кода преобразует наш общий пользовательский интерфейс django rest framework в swagger UI каждый раз, когда мы проверяем наш API в браузере. Это будет намного чище и проще для понимания.
Нам нужно добавить этот блок кода, он должен войти в список urlpatterns
:
path('', schema_view.with_ui('swagger', cache_timeout=0), name='schema-swagger-ui'),
path('redoc/', schema_view.with_ui('redoc', cache_timeout=0), name='schema-redoc'),
path('json/', schema_view.without_ui(cache_timeout=0), name='schema-json'),
Это то, что поможет нам просматривать пользовательский интерфейс swagger с помощью маршрутов.
Теперь, если мы запустим наш сервер, мы должны увидеть следующее:
То, что мы сделали до этого момента — это преобразование нашего drf UI в swagger UI в браузере, мы на самом деле не реализовали.
Если вы посмотрите, вы увидите только конечные точки нашего API, чтобы позволить нашему API отправлять POST
и UPDATE
запросы, нам нужно настроить и это.
Вот пример:
Мы должны иметь возможность отправлять POST
запросы для нашей конечной точки create-product
, но мы не можем, мы видим, что нет полей для добавления наших данных для запроса POST
, но мы можем это изменить.
Нам нужно добавить этот импорт в наш файл views.py
:
from drf_yasg.utils import swagger_auto_schema
swagger_auto_schema
— это декоратор, который помогает нам добавить необходимые нам функции запросов в наши представления, основанные на функциях. Он принимает несколько параметров, но нас интересуют method
и request_body
.
method
определяет тип запроса, который отправляется на нашу конечную точку.
request_body
определяет сериализатор, который конечная точка будет использовать для отправки различных запросов, в основном используемый с методами POST
, PUT
, PATCH
и DELETE
.
Для нашего Create Product View
нам нужно добавить этот блок кода над нашим декоратором api_view
.
@swagger_auto_schema(method='POST', request_body=ProductSerializer)
После добавления этого кода перейдите в браузер и посмотрите на эффект от сделанных изменений, вы должны увидеть следующее:
Теперь мы видим, что существует требуемый объект данных
с полями, которые мы указали в нашем классе сериализатора, который мы будем использовать для отправки POST
запроса. Чтобы отправить запрос, нажмите на кнопку Try it out
, заполните объект данных (если необходимо) и нажмите Execute
.
Теперь нам нужно сделать то же самое, что мы сделали с нашим Create Product View
для других представлений. Добавляем декоратор swagger_auto_schema
над декоратором api_view
каждого представления с соответствующими методами и сериализатором request_body.
Чтение представления продукта
@swagger_auto_schema(method='GET')
Обновить представление продукта
@swagger_auto_schema(method='PATCH', request_body=UpdateProductSerializer)
Удалить представление продукта
@swagger_auto_schema(method='POST', request_body=ProductSerializer)
Теперь запустите ваш сервер и увидите, как новые изменения вступают в силу.
Теперь вы можете реализовать swagger UI в drf, используя представления на основе функций.
Если вы нашли эту статью интересной и информативной, пожалуйста, оставьте лайк и поделитесь, а если у вас остались вопросы, оставьте их в разделе комментариев ниже.
Будьте здоровы!!!