Реализация Swagger с использованием представлений на основе функций в drf

Здравствуйте друзья, в этой статье мы рассмотрим реализацию swagger UI с использованием функциональных представлений в django rest framework (drf).

Я решил написать статью об этом, потому что недавно я столкнулся с различными проблемами при попытке добавить базовый функционал swagger UI в мой API, я использовал представления на основе функций вместо более популярного подхода на основе классов.

В этой статье мы создадим базовый API продукта с CRUD-приложениями, используя представления на основе функций, а затем добавим swagger UI, чтобы сделать наш API более презентабельным.

Настройка среды разработки

Нам нужно создать наш проект 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, используя представления на основе функций.
Если вы нашли эту статью интересной и информативной, пожалуйста, оставьте лайк и поделитесь, а если у вас остались вопросы, оставьте их в разделе комментариев ниже.
Будьте здоровы!!!

Оцените статью
Procodings.ru
Добавить комментарий