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 相关文章推荐
Python使用multiprocessing创建进程的方法
Jun 04 Python
Python操作MongoDB数据库的方法示例
Jan 04 Python
将字典转换为DataFrame并进行频次统计的方法
Apr 08 Python
Python3实现转换Image图片格式
Jun 21 Python
解析Python3中的Import
Oct 13 Python
python3 pillow模块实现简单验证码
Oct 31 Python
使用python+poco+夜神模拟器进行自动化测试实例
Apr 23 Python
python实现读取类别频数数据画水平条形图案例
Apr 24 Python
python中yield的用法详解
Jan 13 Python
Python实现粒子群算法的示例
Feb 14 Python
教你如何使用Python Tkinter库制作记事本
Jun 10 Python
ubuntu安装jupyter并设置远程访问的实现
Mar 31 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将图片保存为不同尺寸图片的图片类实例
2015/03/30 PHP
Zend Framework动作助手(Zend_Controller_Action_Helper)用法详解
2016/03/05 PHP
php实现将数据做成json的格式给前端使用
2018/08/21 PHP
PHP如何使用JWT做Api接口身份认证的实现
2020/02/03 PHP
ExtJS Grid使用SimpleStore、多选框的方法
2009/11/20 Javascript
Javascript图像处理思路及实现代码
2012/12/25 Javascript
使用FlexiGrid实现Extjs表格效果方法分享
2014/12/16 Javascript
jQuery插件pagination实现分页特效
2015/04/12 Javascript
js实现精美的图片跟随鼠标效果实例
2015/05/16 Javascript
JavaScript+html5 canvas绘制的小人效果
2016/01/27 Javascript
JS实现iframe编辑器光标位置插入内容的方法(兼容IE和Firefox)
2016/06/24 Javascript
用JS中split方法实现彩色文字背景效果实例
2016/08/24 Javascript
Vue.js移动端左滑删除组件的实现代码
2017/09/08 Javascript
webpack+vue-cil中proxyTable处理跨域的方法
2018/07/20 Javascript
angular4强制刷新视图的方法
2018/10/09 Javascript
[49:21]完美世界DOTA2联赛循环赛 Ink Ice vs LBZS BO2第二场 11.05
2020/11/06 DOTA
python装饰器decorator介绍
2014/11/21 Python
Python中用memcached来减少数据库查询次数的教程
2015/04/07 Python
Python3将数据保存为txt文件的方法
2019/09/12 Python
关于python3.9安装wordcloud出错的问题及解决办法
2020/11/02 Python
详解Html5微信支付爬坑之路
2018/07/24 HTML / CSS
学生学习总结的自我评价
2013/10/22 职场文书
小学运动会表扬稿
2014/01/19 职场文书
深入开展党的群众路线教育实践活动方案
2014/02/04 职场文书
科级干部考察材料
2014/02/15 职场文书
公开服务承诺制度
2014/03/26 职场文书
领导班子个人对照检查剖析材料
2014/09/29 职场文书
小学教师师德整改措施
2014/09/29 职场文书
2015年乡镇卫生院工作总结
2015/04/22 职场文书
2015年商场工作总结
2015/04/27 职场文书
立案决定书范文
2015/06/24 职场文书
水浒传读书笔记
2015/06/25 职场文书
2016国培学习心得体会
2016/01/08 职场文书
2019银行竞聘书
2019/06/21 职场文书
导游词之秦皇岛燕塞湖
2020/01/03 职场文书
导游词之寿县报恩寺
2020/01/19 职场文书