Подтвердить что ты не робот

Как сгенерировать список сообщений ответа в django rest swagger?

Я обновил Django Rest Framework до 3.5.0 вчера, потому что мне нужно красивое создание схемы.

Я использую Django Rest Swagger для документирования моего API, но не знаю, как перечислять все возможные ответные сообщения, которые предоставляет конечная точка API.

Кажется, что есть автоматическая генерация сообщения успеха, соответствующее действию, которое выполняет моя конечная точка. Таким образом, POST-команды генерируют 201 код ответа без описания.

введите описание изображения здесь

Как я могу добавить все ответные сообщения, которые предоставляет моя конечная точка, и дать им несколько описаний?

Я использую

djangorestframework==3.5.0

django-rest-swagger==2.0.7

4b9b3361

Ответ 1

А, наконец, понял.

Но! Это взломать взломать - и, возможно, drf + drf swagger не поддерживает это; В основном проблема не связана с кодом drf и drf, а скорее с кодеком openapi, посмотрите сами:

def _get_responses(link):
    """
    Returns minimally acceptable responses object based
    on action / method type.
    """
    template = {'description': ''}
    if link.action.lower() == 'post':
        return {'201': template}
    if link.action.lower() == 'delete':
        return {'204': template}
    return {'200': template}

Вышеуказанный код можно найти по адресу: openapi_codec/encode.py - github Это никак не связано с трюком drf или drf - только для каждой ссылки (например: GET/api/v1/test/) создайте шаблон с пустым описанием.

Конечно, есть возможность преодолеть эту проблему. Но, как я уже сказал, это взломать хак:) Я расскажу вам пример:

docs_swagger.views.py

from rest_framework import exceptions
from rest_framework.permissions import AllowAny
from rest_framework.renderers import CoreJSONRenderer
from rest_framework.response import Response
from rest_framework.views import APIView
from rest_framework_swagger import renderers

from docs_swagger.schema_generator import CustomSchemaGenerator


def get_swagger_view(title=None, url=None):
    """
    Returns schema view which renders Swagger/OpenAPI.

    (Replace with DRF get_schema_view shortcut in 3.5)
    """
    class SwaggerSchemaView(APIView):
        _ignore_model_permissions = True
        exclude_from_schema = True
        permission_classes = [AllowAny]
        renderer_classes = [
            CoreJSONRenderer,
            renderers.OpenAPIRenderer,
            renderers.SwaggerUIRenderer
        ]

        def get(self, request):
            generator = CustomSchemaGenerator(title=title, url=url)  # this is altered line
            schema = generator.get_schema(request=request)
            if not schema:
                raise exceptions.ValidationError(
                    'The schema generator did not return a schema   Document'
                )
            return Response(schema)

    return SwaggerSchemaView.as_view()

То, что я делаю в CustomSchemaGenerator, выглядит следующим образом:

docs_swagger.schema_generator.py

import urlparse
import coreapi
from rest_framework.schemas import SchemaGenerator

from openapi_codec import encode


def _custom_get_responses(link):
    detail = False
    if '{id}' in link.url:
        detail = True
    return link._responses_docs.get(
        '{}_{}'.format(link.action, 'list' if not detail else 'detail'),
        link._responses_docs
    )


# Very nasty; Monkey patching;
encode._get_responses = _custom_get_responses


class CustomSchemaGenerator(SchemaGenerator):

    def get_link(self, path, method, view):
        """
        Return a `coreapi.Link` instance for the given endpoint.
        """
        fields = self.get_path_fields(path, method, view)
        fields += self.get_serializer_fields(path, method, view)
        fields += self.get_pagination_fields(path, method, view)
        fields += self.get_filter_fields(path, method, view)

        if fields and any([field.location in ('form', 'body') for field in fields]):
            encoding = self.get_encoding(path, method, view)
        else:
            encoding = None

        description = self.get_description(path, method, view)

        if self.url and path.startswith('/'):
            path = path[1:]

        # CUSTOM
        data_link = coreapi.Link(
            url=urlparse.urljoin(self.url, path),
            action=method.lower(),
            encoding=encoding,
            fields=fields,
            description=description
        )

        data_link._responses_docs = self.get_response_docs(path, method, view)

        return data_link

    def get_response_docs(self, path, method, view):
        return view.responses_docs if hasattr(view, 'responses_docs') else {'200': {
            'description': 'No response docs definition found.'}
        }

И наконец:

my_view.py

class TestViewSet(viewsets.ModelViewSet):
    queryset = Test.objects.all()
    serializer_class = TestSerializer

    responses_docs = {
        'get_list': {
            '200': {
                'description': 'Return the list of the Test objects.',
                'schema': {
                    'type': 'array',
                    'items': {
                        'type': 'object',
                        'properties': {
                            'id': {
                                'type': 'integer'
                            }
                        }
                    }
                }
            },
            '404': {
                'description': 'Not found',
                'schema': {
                    'type': 'object',
                    'properties': {
                        'message': {
                            'type': 'string'
                        }
                    }
                },
                'example': {
                    'message': 'Not found.'
                }
            }
        },
        'get_detail': {
            '200': {
                'description': 'Return single Test object.',
                'schema': {
                    'type': 'object',
                    'properties': {
                        'id': {
                            'type': 'integer'
                        }
                    }
                }
            },
            '404': {
                'description': 'Not found.',
                'schema': {
                    'type': 'object',
                    'properties': {
                        'message': {
                            'type': 'string'
                        }
                    }
                },
                'example': {
                    'message': 'Not found.'
                }
            }
        }
    }

Я считаю это скорее забавным, чем реальным решением. Реального решения, вероятно, невозможно достичь в текущем состоянии. Может быть, вы должны спросить у создателей drf-swagger - есть ли у них планы поддержать ответы?

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

Счастливое кодирование:)