Django REST Framework: Как Автоматически Сгенерировать Swagger-документацию для API, Когда у Объекта Нет get_absolute_url?

Краткий обзор Swagger (OpenAPI) и его преимущества

Swagger (теперь известный как OpenAPI) – это спецификация для описания интерфейсов REST API. Преимущества Swagger: автоматическая генерация документации, возможность интерактивного тестирования API, и генерация клиентского кода.

Django REST Framework (DRF): быстрое создание API

Django REST Framework (DRF) – мощный и гибкий инструмент для создания RESTful API в Django. Он предоставляет сериализаторы, представления и другие компоненты, упрощающие разработку API.

Проблема: Отсутствие get_absolute_url у модели и его влияние на Swagger

DRF часто использует get_absolute_url для автоматического создания ссылок на объекты. Когда модель не имеет этого метода, авто-генерация Swagger-документации может быть затруднена, особенно для endpoints, возвращающих детализированную информацию об объекте.

Автоматическая генерация Swagger-документации с DRF Spectular

Установка и настройка DRF Spectular

DRF Spectular – это библиотека, которая автоматически генерирует OpenAPI схемы для DRF API. Установка:

pip install drf-spectacular

Базовая конфигурация schemas в settings.py

Добавьте drf_spectacular в INSTALLED_APPS и настройте SPECTACULAR_SETTINGS:

INSTALLED_APPS = [
    ...
    'rest_framework',
    'drf_spectacular',
]

SPECTACULAR_SETTINGS = {
    'TITLE': 'Your Project API',
    'VERSION': '1.0.0',
    'SERVE_INCLUDE_SCHEMA': False, # optional, but useful for enums/choices on schema gen
}

Просмотр сгенерированной Swagger-документации

Добавьте URL для просмотра схемы в urls.py:

from django.urls import path, include
from drf_spectacular.views import SpectacularAPIView, SpectacularRedocView, SpectacularSwaggerView

urlpatterns = [
    path('api/schema/', SpectacularAPIView.as_view(), name='schema'),
    # Optional UI:
    path('api/schema/swagger-ui/', SpectacularSwaggerView.as_view(url_name='schema'), name='swagger-ui'),
    path('api/schema/redoc/', SpectacularRedocView.as_view(url_name='schema'), name='redoc'),
]

Теперь можно просмотреть Swagger UI по адресу /api/schema/swagger-ui/.

Решение проблемы отсутствия get_absolute_url

Понимание AutoSchema и его работы

AutoSchema – класс DRF Spectular, который автоматически генерирует OpenAPI схему на основе представлений DRF. Он анализирует сериализаторы, поля и отношения между моделями.

Создание кастомного AutoSchema класса

Создадим кастомный класс AutoSchema, чтобы переопределить логику генерации URL.

from drf_spectacular.openapi import AutoSchema
from rest_framework.request import Request
from rest_framework.serializers import Serializer

class CustomAutoSchema(AutoSchema):
    def get_operation_id(self, path: str, method: str) -> str:
        operation_id = super().get_operation_id(path, method)
        # Дополнительная логика для кастомизации operation_id, если необходимо
        return operation_id

    def get_reference_name(self, component: object) -> str:
        """Override to customize how schema components are named"""
        if isinstance(component, Serializer):
            return component.__class__.__name__  # Use serializer name
        return super().get_reference_name(component)

    def get_path_parameters(self, path: str, method: str) -> list[dict]:
            """Override to customize or add path parameters to the schema"""
            parameters = super().get_path_parameters(path, method)
            # Example: Add a parameter if it's missing
            if not any(p['name'] == 'some_param' for p in parameters):
                parameters.append({
                    'name': 'some_param',
                    'in': 'query',
                    'description': 'A description for the parameter',
                    'schema': {'type': 'string'}
                })
            return parameters
Реклама

Переопределение методов для генерации URL’ов (например, get_operation_id)

Метод get_operation_id позволяет кастомизировать ID операции в Swagger-документации. Другие полезные методы:

  • get_path_parameters: изменение параметров пути.
  • get_pagination_parameters: настройка параметров пагинации.

Использование @extend_schema_field для документирования полей связанных сущностей

@extend_schema_field позволяет добавить документацию к полям, которые не имеют прямого отношения к сериализатору (например, поля, вычисляемые в методах модели).

Пример реализации: Автоматическая генерация URL для API

Определение моделей Django (пример: Product)

from django.db import models

class Product(models.Model):
    name = models.CharField(max_length=255)
    description = models.TextField()
    price = models.DecimalField(max_digits=10, decimal_places=2)

    def __str__(self):
        return self.name

    # get_absolute_url отсутствует специально

Создание сериализаторов (serializers.py)

from rest_framework import serializers
from .models import Product

class ProductSerializer(serializers.ModelSerializer):
    class Meta:
        model = Product
        fields = ['id', 'name', 'description', 'price']

Создание представлений (views.py) с использованием кастомного AutoSchema

from rest_framework import generics
from .models import Product
from .serializers import ProductSerializer
from .schemas import CustomAutoSchema

class ProductList(generics.ListCreateAPIView):
    queryset = Product.objects.all()
    serializer_class = ProductSerializer
    schema = CustomAutoSchema()

class ProductDetail(generics.RetrieveUpdateDestroyAPIView):
    queryset = Product.objects.all()
    serializer_class = ProductSerializer
    schema = CustomAutoSchema()

Настройка URL patterns (urls.py)

from django.urls import path
from . import views

urlpatterns = [
    path('products/', views.ProductList.as_view()),
    path('products/<int:pk>/', views.ProductDetail.as_view()),
]

Продвинутые техники и советы

Обработка сложных случаев и связей между моделями

Для сложных случаев, таких как вложенные сериализаторы или отношения многие-ко-многим, необходимо более детально настраивать AutoSchema и сериализаторы. Используйте @extend_schema_field для документирования полей, которые не отображаются напрямую в сериализаторе.

Добавление описаний и примеров к полям с помощью extend_schema_field и OpenApiParameter

Используйте extend_schema_field для добавления более подробной информации о полях:

from drf_spectacular.utils import extend_schema_field, OpenApiTypes
from rest_framework import serializers

class ProductSerializer(serializers.ModelSerializer):
    custom_field = serializers.SerializerMethodField()

    class Meta:
        model = Product
        fields = ['id', 'name', 'description', 'price', 'custom_field']

    @extend_schema_field(OpenApiTypes.STR)
    def get_custom_field(self, obj):
        return 'Some calculated value'

Интеграция с другими инструментами документирования (Redoc)

DRF Spectular также поддерживает интеграцию с Redoc, еще одним инструментом для документирования API.

Советы по поддержке актуальности Swagger-документации

  • Регулярно обновляйте схему после изменений в API.
  • Используйте CI/CD для автоматической генерации и публикации документации.
  • Пишите понятные описания для каждого поля и параметра.

Добавить комментарий