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下如何让web元素的生成更简单的分析
Jul 17 Python
rhythmbox中文名乱码问题解决方法
Sep 06 Python
python中如何使用朴素贝叶斯算法
Apr 06 Python
mysql 之通过配置文件链接数据库
Aug 12 Python
Django 模型类(models.py)的定义详解
Jul 19 Python
使用 Django Highcharts 实现数据可视化过程解析
Jul 31 Python
Python 实现的 Google 批量翻译功能
Aug 26 Python
pytorch加载自定义网络权重的实现
Jan 07 Python
python构造函数init实例方法解析
Jan 19 Python
VS2019+python3.7+opencv4.1+tensorflow1.13配置详解
Apr 16 Python
浅谈Django前端后端值传递问题
Jul 15 Python
Python数据可视化之基于pyecharts实现的地理图表的绘制
Jun 10 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
初学者入门:细述PHP4的核心Zend
2006/09/05 PHP
phpmyadmin 常用选项设置详解版
2010/03/07 PHP
PHP判断FORM表单或URL参数来的数据是否为整数的方法
2016/03/25 PHP
浅谈PHP中的错误处理和异常处理
2017/02/04 PHP
通过源码解析Laravel的依赖注入
2018/01/22 PHP
javascript 匿名函数的理解(透彻版)
2010/01/28 Javascript
jquery更换文章内容与改变字体大小代码
2013/09/30 Javascript
JavaScript 基础函数_深入剖析变量和作用域
2016/05/18 Javascript
JavaScript验证知识整理
2017/03/24 Javascript
js实现简单模态框实例
2018/11/16 Javascript
Vue脚手架编写试卷页面功能
2020/03/17 Javascript
[10:54]Team Spirit vs Navi
2018/06/07 DOTA
Python聊天室实例程序分享
2016/01/05 Python
pandas DataFrame数据转为list的方法
2018/04/11 Python
详解python读取image
2019/04/03 Python
Python3 sys.argv[ ]用法详解
2019/10/24 Python
Python(PyS60)实现简单语音整点报时
2019/11/18 Python
python深copy和浅copy区别对比解析
2019/12/26 Python
Django model class Meta原理解析
2020/11/14 Python
pandas将list数据拆分成行或列的实现
2020/12/13 Python
HTML5 绘制图像(上)之:关于canvas元素引领下一代web页面的问题
2013/04/24 HTML / CSS
优衣库英国官网:UNIQLO英国
2016/12/25 全球购物
计算机专业应届毕业生自荐信
2013/09/26 职场文书
实习生自我鉴定范文
2013/12/05 职场文书
优秀民警事迹材料
2014/01/29 职场文书
电力公司个人求职信范文
2014/02/04 职场文书
便利店促销方案
2014/02/20 职场文书
房地产营销活动策划方案
2014/09/15 职场文书
个人反四风对照检查材料思想汇报
2014/09/23 职场文书
2014年信息技术工作总结
2014/12/16 职场文书
酒吧七夕情人节宣传语
2015/11/24 职场文书
《没有任何借口》读后感:完美的执行能力
2020/01/07 职场文书
MySql新手入门的基本操作汇总
2021/05/13 MySQL
彻底解决MySQL使用中文乱码的方法
2022/01/22 MySQL
canvas实现贪食蛇的实践
2022/02/15 Javascript
Java 超详细讲解IO操作字节流与字符流
2022/03/25 Java/Android