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 MySQLdb模块连接操作mysql数据库实例
Apr 08 Python
Python2.x中文乱码问题解决方法
Jun 02 Python
python按照多个条件排序的方法
Feb 08 Python
浅谈python新式类和旧式类区别
Apr 26 Python
numpy数组之存取文件的实现示例
May 24 Python
jupyter notebook 多环境conda kernel配置方式
Apr 10 Python
解决Jupyter Notebook使用parser.parse_args出现错误问题
Apr 20 Python
Python读入mnist二进制图像文件并显示实例
Apr 24 Python
Jupyter打开图形界面并画出正弦函数图像实例
Apr 24 Python
Python使用plt.boxplot() 参数绘制箱线图
Jun 04 Python
Python如何向SQLServer存储二进制图片
Jun 08 Python
pip已经安装好第三方库但pycharm中import时还是标红的解决方案
Oct 09 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
构建简单的Webmail系统
2006/10/09 PHP
PHP入门学习的几个不错的实例代码
2008/07/13 PHP
php版微信公众平台入门教程之开发者认证的方法
2016/09/26 PHP
javascript实现的像java、c#之类的sleep暂停的函数代码
2010/03/04 Javascript
jquery获取ASP.NET服务器端控件dropdownlist和radiobuttonlist生成客户端HTML标签后的value和text值
2010/06/28 Javascript
nodejs实现的一个简单聊天室功能分享
2014/12/06 NodeJs
js小数计算小数点后显示多位小数的实现方法
2016/05/30 Javascript
jQuery滚动新闻实现代码
2016/06/26 Javascript
Move.js入门
2017/02/08 Javascript
JS正则表达式验证账号、手机号、电话和邮箱是否合法
2017/03/08 Javascript
微信小程序商品详情页的底部弹出框效果
2020/11/16 Javascript
jQuery实现基本隐藏与显示效果的方法详解
2018/09/05 jQuery
解决vue A对象赋值给B对象,修改B属性会影响到A的问题
2018/09/25 Javascript
vue观察模式浅析
2018/09/25 Javascript
async/await优雅的错误处理方法总结
2019/01/30 Javascript
微信小程序rich-text富文本用法实例分析
2019/05/20 Javascript
js实现页面导航层级指示效果
2020/08/25 Javascript
Python中关于字符串对象的一些基础知识
2015/04/08 Python
在ironpython中利用装饰器执行SQL操作的例子
2015/05/02 Python
浅析使用Python操作文件
2017/07/31 Python
python图书管理系统
2020/04/05 Python
Django-Model数据库操作(增删改查、连表结构)详解
2019/07/17 Python
Python Request爬取seo.chinaz.com百度权重网站的查询结果过程解析
2019/08/13 Python
基于python实现学生信息管理系统
2019/11/22 Python
django实现日志按日期分割
2020/05/21 Python
一款基于css3的动画按钮代码教程
2014/11/23 HTML / CSS
屈臣氏泰国官网:Watsons TH
2021/02/23 全球购物
什么是反射
2012/03/17 面试题
中学校庆方案
2014/03/17 职场文书
市场营销工作计划书
2014/05/06 职场文书
土建工程师岗位职责
2014/06/10 职场文书
2015年社区环境卫生工作总结
2015/04/21 职场文书
上课迟到检讨书
2015/05/06 职场文书
水浒传读书笔记
2015/06/25 职场文书
学校教学管理制度
2015/08/06 职场文书
领导干部学习心得体会
2016/01/23 职场文书