为什么要指定swagger的api参数

api的参数有多种类型:

query 参数,如 /users"" src="/UploadFiles/2021-04-08/20200707091646.jpg">

难点

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

广告合作:本站广告合作请联系QQ:858582 申请时备注:广告合作(否则不回)
免责声明:本站资源来自互联网收集,仅供用于学习和交流,请遵循相关法律法规,本站一切资源不代表本站立场,如有侵权、后门、不妥请联系本站删除!

《魔兽世界》大逃杀!60人新游玩模式《强袭风暴》3月21日上线

暴雪近日发布了《魔兽世界》10.2.6 更新内容,新游玩模式《强袭风暴》即将于3月21 日在亚服上线,届时玩家将前往阿拉希高地展开一场 60 人大逃杀对战。

艾泽拉斯的冒险者已经征服了艾泽拉斯的大地及遥远的彼岸。他们在对抗世界上最致命的敌人时展现出过人的手腕,并且成功阻止终结宇宙等级的威胁。当他们在为即将于《魔兽世界》资料片《地心之战》中来袭的萨拉塔斯势力做战斗准备时,他们还需要在熟悉的阿拉希高地面对一个全新的敌人──那就是彼此。在《巨龙崛起》10.2.6 更新的《强袭风暴》中,玩家将会进入一个全新的海盗主题大逃杀式限时活动,其中包含极高的风险和史诗级的奖励。

《强袭风暴》不是普通的战场,作为一个独立于主游戏之外的活动,玩家可以用大逃杀的风格来体验《魔兽世界》,不分职业、不分装备(除了你在赛局中捡到的),光是技巧和战略的强弱之分就能决定出谁才是能坚持到最后的赢家。本次活动将会开放单人和双人模式,玩家在加入海盗主题的预赛大厅区域前,可以从强袭风暴角色画面新增好友。游玩游戏将可以累计名望轨迹,《巨龙崛起》和《魔兽世界:巫妖王之怒 经典版》的玩家都可以获得奖励。