Django REST Swagger实现指定api参数


Posted in Python onJuly 07, 2020

为什么要指定swagger的api参数

api的参数有多种类型:

query 参数,如 /users?role=admin

path 参数,如 /users/{id}

header 参数,如 X-MyHeader: Value

body 参数,描述POST,PUT,PATCH请求的body

form 参数,描述 Content-Type of application/x-www-form-urlencoded 和 multipart/form-data 的请求报文body的参数

swagger指定api参数就可以在文档相应的api条目中显示出api的描述、正常输出、异常输出、参数的名称、描述、是否必填、值类型、参数类型对不同的参数类型有不同的显示效果。swagger是可交互的api文档,可以直接填入文档显示的参数的值并发送请求,返回的结果就会在文档中显示。

Django REST Swagger实现指定api参数

难点

对 Django REST Swagger < 2 的版本,要指定swagger的api参数非常容易,只要将相关说明以特定格式和yaml格式写在相应api的视图函数的文档字符串(DocStrings)里,swagger就会自动渲染到文档中。比如这样的格式:

def cancel(self, request, id):
 """
 desc: 取消任务,进行中的参与者得到报酬
 ret: msg
 err: 404页面/msg
 input:
 - name: id
 desc: 任务id
 type: string
 required: true
 location: path
 """

但是在2.0版本之后,Django REST Swagger废弃了对yaml文档字符串的支持,不会渲染出任何内容。

一种解决方案

在Django REST framework基于类的api视图中定义filter_class过滤出模型(models)的特定字段,swagger会根据这些字段来渲染。

from django_filters.rest_framework.filterset import FilterSet

class ProductFilter(FilterSet):

 class Meta(object):
 models = models.Product
 fields = (
  'name', 'category', 'id', )

class PurchasedProductsList(generics.ListAPIView):
 """
 Return a list of all the products that the authenticated
 user has ever purchased, with optional filtering.
 """
 model = Product
 serializer_class = ProductSerializer
 filter_class = ProductFilter

 def get_queryset(self):
 user = self.request.user
 return user.purchase_set.all()

这个解决方法只解决了一半问题,只能用在面向模型的api,只能过滤模型的一些字段,而且api参数名与模型字段名不一致时还要额外处理。

启发

查阅Django REST Swagger的文档,Advanced Usage提到,基于类的文档api视图是这样的:

from rest_framework.response import Response
from rest_framework.schemas import SchemaGenerator
from rest_framework.views import APIView
from rest_framework_swagger import renderers

class SwaggerSchemaView(APIView):
 permission_classes = [AllowAny]
 renderer_classes = [
 renderers.OpenAPIRenderer,
 renderers.SwaggerUIRenderer
 ]

 def get(self, request):
 generator = SchemaGenerator()
 schema = generator.get_schema(request=request)

 return Response(schema)

说明文档是根据schema变量来渲染的,所以可以通过重载schema变量,利用yaml包解析出api视图函数的文档字符串中的参数定义赋值给schema变量。

更好的解决方法

创建schema_view.py:

from django.utils.six.moves.urllib import parse as urlparse
from rest_framework.schemas import AutoSchema
import yaml
import coreapi
from rest_framework_swagger.views import get_swagger_view

class CustomSchema(AutoSchema):
 def get_link(self, path, method, base_url):

 view = self.view
 method_name = getattr(view, 'action', method.lower())
 method_docstring = getattr(view, method_name, None).__doc__
 _method_desc = ''

 fields = self.get_path_fields(path, method)

 try:
  a = method_docstring.split('---')
 except:
  fields += self.get_serializer_fields(path, method)
 else:
  yaml_doc = None
  if method_docstring:
  try:
   yaml_doc = yaml.load(a[1])
  except:
   yaml_doc = None

  # Extract schema information from yaml

  if yaml_doc and type(yaml_doc) != str:
  _desc = yaml_doc.get('desc', '')
  _ret = yaml_doc.get('ret', '')
  _err = yaml_doc.get('err', '')
  _method_desc = _desc + '\n<br/>' + 'return: ' + _ret + '<br/>' + 'error: ' + _err
  params = yaml_doc.get('input', [])

  for i in params:
   _name = i.get('name')
   _desc = i.get('desc')
   _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 = a[0]
  fields += self.get_serializer_fields(path, method)

 fields += self.get_pagination_fields(path, method)
 fields += self.get_filter_fields(path, method)

 manual_fields = self.get_manual_fields(path, method)
 fields = self.update_fields(fields, manual_fields)

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

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

 return coreapi.Link(
  url=urlparse.urljoin(base_url, path),
  action=method.lower(),
  encoding=encoding,
  fields=fields,
  description=_method_desc
 )

schema_view = get_swagger_view(title='API')

urls.py中指向schema_view:

from .schema_view import schema_view

urlpatterns = [
 url(r'^v1/api/', include([
 url(r'^doc/', schema_view),
 ])),

然后在需要指定api参数的视图类(如APIView或ModelViewSet)中重载schema:

schema = CustomSchema()

以上这篇Django REST Swagger实现指定api参数就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持三水点靠木。

Python 相关文章推荐
Python3 能振兴 Python的原因分析
Nov 28 Python
Centos5.x下升级python到python2.7版本教程
Feb 14 Python
初步探究Python程序的执行原理
Apr 11 Python
基于python yield机制的异步操作同步化编程模型
Mar 18 Python
python机器学习理论与实战(六)支持向量机
Jan 19 Python
Python实现时钟显示效果思路详解
Apr 11 Python
Django项目中用JS实现加载子页面并传值的方法
May 28 Python
Python中GIL的使用详解
Oct 03 Python
python批量获取html内body内容的实例
Jan 02 Python
Django集成搜索引擎Elasticserach的方法示例
Jun 04 Python
Python中的十大图像处理工具(小结)
Jun 10 Python
Django中日期时间型字段进行年月日时分秒分组统计
Nov 27 Python
python中查看.db文件中表格的名字及表格中的字段操作
Jul 07 #Python
python db类用法说明
Jul 07 #Python
python文件编写好后如何实践
Jul 07 #Python
python 删除excel表格重复行,数据预处理操作
Jul 06 #Python
pandas.DataFrame.drop_duplicates 用法介绍
Jul 06 #Python
TensorFlow Autodiff自动微分详解
Jul 06 #Python
Keras loss函数剖析
Jul 06 #Python
You might like
使用PHP和XSL stylesheets转换XML文档
2006/10/09 PHP
php执行sql语句的写法
2009/03/10 PHP
PHP生成随机密码类分享
2014/06/25 PHP
php中青蛙跳台阶的问题解决方法
2018/10/14 PHP
javascript web页面刷新的方法收集
2009/07/02 Javascript
MooTools 1.2介绍
2009/09/14 Javascript
jquery load事件(callback/data)使用方法及注意事项
2013/02/06 Javascript
关于JS判断图片是否加载完成且获取图片宽度的方法
2013/04/09 Javascript
简要了解jQuery移动web开发的响应式布局设计
2015/12/04 Javascript
JavaScript实现修改伪类样式
2017/11/27 Javascript
vue中使用protobuf的过程记录
2018/10/26 Javascript
Vue如何使用混合Mixins和插件开发详解
2020/02/05 Javascript
vue组件开发之slider组件使用详解
2020/08/21 Javascript
vue内置组件keep-alive事件动态缓存实例
2020/10/30 Javascript
vue+swiper实现左右滑动的测试题功能
2020/10/30 Javascript
vscode自定义vue模板的实现
2021/01/27 Vue.js
[03:59]5分钟带你了解什么是DOTA2(第二期)
2017/02/07 DOTA
[01:56]无止竞 再出发——中国军团出征2017年DOTA2国际邀请赛
2017/07/05 DOTA
跟老齐学Python之玩转字符串(1)
2014/09/14 Python
python读取有密码的zip压缩文件实例
2019/02/08 Python
使用pyinstaller打包PyQt4程序遇到的问题及解决方法
2019/06/24 Python
python代码xml转txt实例
2020/03/10 Python
python简单实现9宫格图片实例
2020/09/03 Python
python绘制雷达图实例讲解
2021/01/03 Python
西班牙自行车和跑步商店:Alltricks
2018/07/07 全球购物
J2EE是技术还是平台还是框架
2016/08/14 面试题
销售人员个人求职信
2013/09/26 职场文书
畜牧兽医本科生个人的自我评价
2013/10/11 职场文书
经济与贸易专业应届生求职信
2013/11/19 职场文书
企业消防安全责任书
2014/07/23 职场文书
社区党员公开承诺书
2014/08/30 职场文书
新年晚会主持词开场白
2015/05/28 职场文书
篮球拉拉队口号
2015/12/25 职场文书
2016年第104个国际护士节活动总结
2016/04/06 职场文书
手把手教你导入Go语言第三方库
2021/08/04 Golang
Python+腾讯云服务器实现每日自动健康打卡
2021/12/06 Python