如何在django休息中生成响应消息列表? [英] How to generate list of response messages in django rest swagger?

查看:342
本文介绍了如何在django休息中生成响应消息列表?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我昨天将Django Rest Framework升级到3.5.0,因为我需要很好的模式生成。



我正在使用 Django Rest Swagger 记录我的API,但不知道如何列出API端点提供的所有可能的响应消息。



似乎自动生成与我的端点正在执行的动作相对应的成功消息。
所以POST操作生成201个响应代码,没有任何描述。





我将如何添加我的端点提供的所有响应消息,并给他们一些描述?



我正在使用



djangorestframework == 3.5.0



django-rest-swagger == 2.0.7

解决方案

啊,终于找到了。



但是!这是黑客攻击 - 可能drf + drf swagger不支持;基本上,问题没有连接到drf和drf swagger代码,而是openapi编解码器,看看你自己:

  def _get_responses(link )

在操作/方法类型上返回最低限度可接受的响应对象


template = {'description':''}
如果link.action.lower()=='post':
return {'201':template}
如果link.action.lower()=='delete':
return {'204':template}
return {'200':template}

以上代码可以在以下网址找到: openapi_codec / encode.py -



快乐编码:)


I have upgraded Django Rest Framework to 3.5.0 yesterday because I need nice schema generation.

I am using Django Rest Swagger to document my API but don't know how to list all possible response messages that an API endpoint provides.

It seems that there is automatic generation of success message corresponding to the action my endpoint is performing. So POST actions generate 201 response code, without any description.

How would I go about adding all the response messages that my endpoint provides and give them some descriptions?

I am using

djangorestframework==3.5.0

django-rest-swagger==2.0.7

解决方案

Ah, Finally got it.

But! This is hack on hack - and probably drf + drf swagger not support that; Basically the problem is not connected to the drf and drf swagger code, rather the openapi codec, see yourself:

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}

The above code can be found at: openapi_codec/encode.py - github This is not connected in any way with drf or drf swagger - just for each link (eg.: GET /api/v1/test/) create a template with empty description.

Of course there's a possibility to overcome this issue. But as I said - this is hack on hack :) I will share an example with you:

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()

What I do in the CustomSchemaGenerator is as follows:

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.'}
        }

And finally:

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.'
                }
            }
        }
    }

I consider this more like fun instead of a real solution. The real solution is probably impossible to achieve at the current state. Maybe you should ask the creators of drf swagger - do they have plans to support responses?

Anyway, the swagger UI:

Happy coding :)

这篇关于如何在django休息中生成响应消息列表?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆