美文网首页
在djangorestframework中使用yaml格式的注释

在djangorestframework中使用yaml格式的注释

作者: 爱林林爱生活 | 来源:发表于2017-02-16 17:43 被阅读0次

    0x01

    最近在项目中要对api进行大规模重构,并且工具源码注释生成文档,比较swagger和spihx之后,觉得swagger更适合做api文档,可以在web页面中直接请求对应的api,很是方便。使用最新版的django-rest-swagger(drs)生成djangorestframework(drf)生成文档的时候,drs只会根据视图中的docstring来生成Link(swagger的单条文档记录)的描述,根据ViewSet中的serializer中定义的fields以及pagination_class定义的分页类来生成parameters,如果想要根据文档来插入一些parameters时,可以发现drs的可定制化程度很低,于是我决定做一些定制化。

    0x02 代码

    在制定花的过程中我主要重写了drf中的SchemaGenerator的get_description,把视图中的docstring按照yaml格式解析出来,并且返回docstring中的第一行作为description,如果视图没有docstring的话,_SchemaGenerator会按照视图名称自动生成相应的description。接下来是重写get_link方法,前面说过,一条Link是swagger页面中的一条文档记录,如果有yamlobj的话,则根据固定的格式解析yamlobj,然后解析出来的属性加到Link当中去。最后重写get_swagger_view 方法,使用新写的SchemaGenerator。

    from rest_framework.schemas import SchemaGenerator as _SchemaGenerator
    from rest_framework_swagger import renderers
    from rest_framework.compat import coreapi, urlparse
    from django.utils.encoding import smart_text
    from rest_framework.utils import formatting
    
    class SchemaGenerator(_SchemaGenerator):
        def get_description(self, path, method, view):
            method_name = getattr(view, 'action', method.lower())
            method_docstring = getattr(view, method_name, None).__doc__
            self.yamlobj = None
            if method_docstring:
                method_docstring = formatting.dedent(smart_text(method_docstring))
                self.yamlobj = yaml.load(method_docstring)
                return method_docstring.splitlines()[0]
            return super(SchemaGenerator, self).get_description(path, method, view)
    
        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 isinstance(self.yamlobj, dict):
                    def get_localtion(parameter):
                        if method == 'GET':
                            return 'query'
                        return parameter.get('paramType', 'formData')
                    parameters = self.yamlobj.get('parameters', [])
                    fields += [coreapi.Field(name=x['name'], location=get_localtion(x),     required=x.get('required', True, ), description=x.get('description', ''),     type=x.get('type', 'string')) for x in parameters]
    
                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,
                    description=description
            )
    
    
    def get_swagger_view(title=None, url=None, patterns=None, urlconf=None):
        """
        Returns schema view which renders Swagger/OpenAPI.
        """
        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 = SchemaGenerator(
                    title=title,
                    url=url,
                    patterns=patterns,
                    urlconf=urlconf
                )
                 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()
    

    相关文章

      网友评论

          本文标题:在djangorestframework中使用yaml格式的注释

          本文链接:https://www.haomeiwen.com/subject/hpshwttx.html