Django Rest Swagger 2:到目前为止是否有记录 POST 基于 FUNCTION 的视图请求的参数?
Django Rest Swagger 2: Is there anyway so far to document parameters for POST requests of FUNCTION based views?
我正在尝试将 django-rest-swagger==2.1.1
与我现有的使用 djangorestframework==3.5.3
的项目集成。
该项目有一些基于 Class 的视图和一些基于函数的视图。集成swagger后,对于"Class Based views"的POST请求显示输入框(明显有序列化器),但对于"function based views"不显示。这个问题已经被问过好几次了,我尝试了以下解决方案:
和其他一些人,但对我的情况不起作用。 'function based views' 是否有任何可能的方法,或者我必须将它们转换为基于 class 的视图?
YAML 文档字符串解析器在 REST Swagger>=2.0 中已弃用
我所做的是覆盖 SchemaGenerator class 以按照我自己的约定解析视图的文档字符串。
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.schemas import SchemaGenerator
from rest_framework.views import APIView
from rest_framework_swagger import renderers
import yaml
import coreapi
import urlparse
class SchemaGenerator(SchemaGenerator):
def get_link(self, path, method, view):
"""Custom the coreapi using the func.__doc__ .
if __doc__ of the function exist, use the __doc__ building the coreapi. else use the default serializer.
__doc__ in yaml format, eg:
description: the desc of this api.
parameters:
- name: mobile
desc: the mobile number
type: string
required: true
location: form
- name: promotion
desc: the activity id
type: int
required: true
location: form
"""
fields = self.get_path_fields(path, method, view)
yaml_doc = None
if view and view.__doc__:
try:
yaml_doc = yaml.load(view.__doc__)
except:
yaml_doc = None
if yaml_doc and type(yaml_doc) != str:
_method_desc = yaml_doc.get('description', '')
params = yaml_doc.get('parameters', [])
for i in params:
_name = i.get('name')
_desc = i.get('description')
_required = i.get('required', False)
_type = i.get('type', 'string')
_location = i.get('location', 'form')
field = coreapi.Field(
name=_name,
location=_location,
required=_required,
description=_desc,
type=_type
)
fields.append(field)
else:
_method_desc = view.__doc__ if view and view.__doc__ else ''
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
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=_method_desc
)
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()
在项目结构中的任意位置创建此模块。在 project/urls.py
中从该模块导入 get_swagger_view
。然后,从 django_rest_swagger
模块中删除 get_swagger_view
方法。
参考:Comment by daimon99 in REST Swagger Issues
更新:从 django-rest-framework
版本 3.7 开始,由于上述代码无法运行,存在重大更改,解决方案是 Comment by GuillaumeCisco
您可以使用装饰器:
from rest_framework.decorators import api_view
然后在你的函数上方使用:
@api_view(['POST'])
我正在尝试将 django-rest-swagger==2.1.1
与我现有的使用 djangorestframework==3.5.3
的项目集成。
该项目有一些基于 Class 的视图和一些基于函数的视图。集成swagger后,对于"Class Based views"的POST请求显示输入框(明显有序列化器),但对于"function based views"不显示。这个问题已经被问过好几次了,我尝试了以下解决方案:
和其他一些人,但对我的情况不起作用。 'function based views' 是否有任何可能的方法,或者我必须将它们转换为基于 class 的视图?
YAML 文档字符串解析器在 REST Swagger>=2.0 中已弃用
我所做的是覆盖 SchemaGenerator class 以按照我自己的约定解析视图的文档字符串。
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.schemas import SchemaGenerator
from rest_framework.views import APIView
from rest_framework_swagger import renderers
import yaml
import coreapi
import urlparse
class SchemaGenerator(SchemaGenerator):
def get_link(self, path, method, view):
"""Custom the coreapi using the func.__doc__ .
if __doc__ of the function exist, use the __doc__ building the coreapi. else use the default serializer.
__doc__ in yaml format, eg:
description: the desc of this api.
parameters:
- name: mobile
desc: the mobile number
type: string
required: true
location: form
- name: promotion
desc: the activity id
type: int
required: true
location: form
"""
fields = self.get_path_fields(path, method, view)
yaml_doc = None
if view and view.__doc__:
try:
yaml_doc = yaml.load(view.__doc__)
except:
yaml_doc = None
if yaml_doc and type(yaml_doc) != str:
_method_desc = yaml_doc.get('description', '')
params = yaml_doc.get('parameters', [])
for i in params:
_name = i.get('name')
_desc = i.get('description')
_required = i.get('required', False)
_type = i.get('type', 'string')
_location = i.get('location', 'form')
field = coreapi.Field(
name=_name,
location=_location,
required=_required,
description=_desc,
type=_type
)
fields.append(field)
else:
_method_desc = view.__doc__ if view and view.__doc__ else ''
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
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=_method_desc
)
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()
在项目结构中的任意位置创建此模块。在 project/urls.py
中从该模块导入 get_swagger_view
。然后,从 django_rest_swagger
模块中删除 get_swagger_view
方法。
参考:Comment by daimon99 in REST Swagger Issues
更新:从 django-rest-framework
版本 3.7 开始,由于上述代码无法运行,存在重大更改,解决方案是 Comment by GuillaumeCisco
您可以使用装饰器:
from rest_framework.decorators import api_view
然后在你的函数上方使用:
@api_view(['POST'])