Django REST Swagger实现指定api参数

为什么要指定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 < 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参数就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持我们。

(0)

相关推荐

  • django-rest-framework 自定义swagger过程详解

    前言 之前的文章编写了一个返回json的例子,直接用浏览器进行get请求虽然成功了, 但是接口文档的样式很难看, 不好用. 而且提示没有访问权限. 我们一般都希望能够直接在接口文档中进行请求, 以测试接口, 本篇文章中会给出一个自定义swagger(openapi)的例子. 使接口文档变得美观可用, 可以填写参数, 可以进行请求以观察数据格式, 测试接口是否可用. 环境 workon python35 pip list chardet (3.0.4) coreapi (2.3.3) coresc

  • django-rest-framework解析请求参数过程详解

    前言 我们在django-rest-framework 自定义swagger 文章中编写了接口, 调通了接口文档. 接口文档可以直接填写参数进行请求, 接下来的问题是如何接受参数, 由于请求方式与参数序列化形式的不同, 接收参数的方式也有不同. 前提条件 服务端我们使用django-rest-framework编写接口. class ReturnJson(APIView): coreapi_fields=( DocParam("token"), ) def get(self, requ

  • Python利用Django如何写restful api接口详解

    前言 用Python如何写一个接口呢,首先得要有数据,可以用我们在网站上爬的数据,在上一篇文章中写了如何用Python爬虫,有兴趣的可以看看://www.jb51.net/article/141661.htm 大量的数据保存到数据库比较方便.我用的pymsql,pymsql是Python中操作MySQL的模块,其使用方法和MySQLdb几乎相同.但目前在python3.x中,PyMySQL取代了MySQLdb. 1.连接数据库 # 连接数据库,需指定charset否则可能会报错 db = pym

  • Django REST Swagger实现指定api参数

    为什么要指定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指

  • 简单了解Django ORM常用字段类型及参数配置

    这篇文章主要介绍了简单了解Django ORM常用字段类型及参数配置,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 一.数值型 AutoField对应int(11).自增主键,Django Model默认提供,可以被重写. BooleanField对应tinyint(1).布尔类型字段,一般用于记录状态标记. DecimalField对应decimal.开发对数据精准要求较高大的业务时考虑使用.比如:cash=models.DecimalFie

  • SpringBoot和Swagger结合提高API开发效率

    现在Web开发越来越倾向于前后端分离,前端使用AngularJS,React,Vue等,部署在NodeJS上,后面采用SpringBoot发布Rest服务,前后端进行分离.这样的架构灵活且特别适合大型团队的协作开发. 那么问题来了,因为前端都是和后端通过API进行交互的,那么前后端的Rest API的接口如何进行定义和沟通呢?首先想到的应该就是Swagger. 那么什么是Swagger,Swagger™的目标是为REST APIs 定义一个标准的,与语言无关的接口,使人和计算机在看不到源码或者看

  • 在django view中给form传入参数的例子

    在django的form表单会出现,在form的验证或者保存时需要非form中的field的信息参数.例如在对操作进行记录,我们需要根据将记录的操作人设置为当前的用户,所以在view中我们需要将user的信息传入到form中,方便在form.save()d的方法使用. models # models.py from django.db import models from django.contrib.auth.models import User class Record(models.Mod

  • django 微信网页授权认证api的步骤详解

    微信网页授权认证 根据微信官方文档,网页授权需要四个步骤, - 用户同意授权-获取code - 通过code 获取网页授权access_token - 通过code 获取网页授权access_token - 刷新token - 拉去用户信息scope为snsapi_userinfo -检验授权凭证 access_token是否有效 1 授权 url="https://open.weixin.qq.com/connect/oauth2/authorize?appid={0}&redirec

  • Django中reverse反转并且传递参数的方法

    在写项目的过程中,有些函数不可避免的需要传入参数进去,所以我们在使用reverse进行反转时也需要传递参数.这个时候我们就可以使用 'reverse()' 中的 kwargs 参数了,它将传入一个字典形式的变量.kwargs 也支持传入多个参数 示例代码 首先在Django项目中新建一个'reverse'的app用来测试. 在views.py中写入以下代码 from django.shortcuts import render,redirect,reverse from django.http

  • 用 Django 开发一个 Python Web API的方法步骤

    Django 是 Python 编程语言驱动的一个开源模型-视图-控制器(MVC)风格的 Web 应用程序框架.它是Python API开发中最受欢迎的名称之一,自2005年成立以来,其知名度迅速提升. Django由Django软件基金会(Django Software Foundation)维护,并获得了社区的大力支持,在全球拥有11,600多个成员.在Stack Overflow上,Django大约有191,000个带标签的问题.Spotify,YouTube和Instagram等网站都依

  • 关于swagger配置及踩坑@Api参数postion无效解决接口排序问题

    目录 添加maven依赖 添加配置类 在application.properties中添加配置 添加控制类UserController 请求对象类DTO 响应对象类 最后,上效果图 最后还有个坑 添加maven依赖 <!-- 集成swagger2 --> <dependency> <groupId>io.springfox</groupId> <artifactId>springfox-swagger2</artifactId> &l

  • Django使用rest_framework写出API

    在Django中用rest_framework写API,写了一个用户注册的API,并测试成功. 本人环境:Django==2.2.1:djangorestframework==3.11.0 1.安装djangorestframework (1)终端中输入命令: pip install djangorestframework (2)在settings里面的INSTALL_APP里面,添加rest_framework应用: INSTALL_APP = [ ... 'rest_framework',

  • php指定函数参数默认值示例代码

    例1 复制代码 代码如下: <html><head><title>php函数指定默认值-www.jb51.net</title></head><body><?phpfunction printMe($param = NULL){   print $param;}printMe("This is test");printMe();?> </body></html> 输出结果:Thi

随机推荐