首页 文章

Django休息框架Api文档Swagger 2.0

提问于
浏览
1

我很难配置Swagger UI . 以下是非常简洁的文档:https://django-rest-swagger.readthedocs.io/en/latest/

YAML文档字符串已弃用 . 有人知道如何从python代码中配置Swagger UI(查询参数等)吗?

如果出于某种奇怪的原因是不可能的 . 有没有可行的替代方案,或者对我来说最好是手工编写api文档?

1 回答

  • 4

    好的,找到了 . 这不是理想的解决方案 - 但前端(网络和移动)开发人员需要这样做 - 而且它可以完成这项工作 .

    基本上最新的DRF和Swagger使用 rest_framework.schemas import SchemaGenerator 来提供Swagger的文档 .

    所以我需要对它进行一点延伸:

    # -*- coding: utf-8 -*-
    import urlparse
    
    import coreapi
    from rest_framework.schemas import SchemaGenerator
    
    
    class ParamsSchemaGenerator(SchemaGenerator):
    
        def get_link(self, path, method, callback, view):
            """
            Return a `coreapi.Link` instance for the given endpoint.
            """
            fields = self.get_path_fields(path, method, callback, view)
            fields += self.get_serializer_fields(path, method, callback, view)
            fields += self.get_pagination_fields(path, method, callback, view)
            fields += self.get_filter_fields(path, method, callback, view)
            fields += self.get_docs_fields(path, method, callback, view)  # this is the extended line;
    
            if fields and any([field.location in ('form', 'body') for field in fields]):
                encoding = self.get_encoding(path, method, callback, view)
            else:
                encoding = None
    
            if self.url and path.startswith('/'):
                path = path[1:]
    
            return coreapi.Link(
                url=urlparse.urljoin(self.url, path),
                action=method.lower(),
                encoding=encoding,
                fields=fields
            )
    
        # and this is fully custom additional docs method;
        def get_docs_fields(self, path, method, callback, view):
            fields = []
            if hasattr(view, 'docs_fields'):
                for field in view.docs_fields:
                    field = coreapi.Field(
                        name=field.get('name'),
                        location=field.get('query'),
                        required=field.get('required'),
                        type=field.get('type'),
                        description=field.get('description')
                    )
                    fields.append(field)
    
            return fields
    

    然后我需要定义一个函数,它将使用上面定义的生成器返回模式:

    # -*- coding: utf-8 -*-
    # monkey patching FTW!
    
    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 kolomnie.core.schema.generator import ParamsSchemaGenerator
    
    
    def get_params_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 = ParamsSchemaGenerator(title=title, url=url)
                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()
    

    这就是我把它放在网址中的方式:

    if settings.DEBUG:
        api_views = get_params_swagger_view(title='Some API')
    

    现在更加神奇了,我为视图定义了一个mixin来存储文档字段:

    # -*- coding: utf-8 -*-
    
    
    class DocsMixin(object):
        """
        This mixin can be used to document the query parameters in GET
        if there's no other way to do it. Please refer to the: ParamsSchemaGenerator.get_links
        for more information;
        """
        docs_fields = []
    

    这就是我使用它的方式:

    class BaseSearchResultsView(generics.GenericAPIView, SearchDocs):
        ....
    

    SearchDocs是这样的:

    class SearchDocs(DocsMixin):
        """
        Documents the get query in search;
        """
        docs_fields = [
            {
                'name': 'q',
                'location': 'query',
                'required': False,
                'type': 'string',
                'description': 'The base query for the search;',
            },
        ...
    

    只是发现我不需要mixin :)只需在视图上定义docs_fields .

    可能这不会满足您的所有需求 - 但认为这是一个良好的开端:)

    快乐的编码!

相关问题