网络编程
位置:首页>> 网络编程>> Python编程>> django-rest-framework 自定义swagger过程详解

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

作者:yaominghui  发布时间:2023-01-01 22:05:34 

标签:django,rest,framework,自定义,swagger

前言

之前的文章编写了一个返回json的例子,直接用浏览器进行get请求虽然成功了, 但是接口文档的样式很难看, 不好用. 而且提示没有访问权限.

我们一般都希望能够直接在接口文档中进行请求, 以测试接口, 本篇文章中会给出一个自定义swagger(openapi)的例子. 使接口文档变得美观可用, 可以填写参数, 可以进行请求以观察数据格式, 测试接口是否可用.

环境


workon python35
pip list

chardet (3.0.4)
coreapi (2.3.3)
coreschema (0.0.4)
Django (1.11.6)
django-rest-swagger (2.1.2)
django-simple-serializer (2.0.7)
djangorestframework (3.7.1)
future (0.16.0)
idna (2.6)
itypes (1.1.0)
Jinja2 (2.9.6)
MarkupSafe (1.0)
openapi-codec (1.3.2)
pip (9.0.1)
pytz (2017.2)
requests (2.18.4)
setuptools (36.6.0)
simplejson (3.11.1)
uritemplate (3.0.0)
urllib3 (1.22)
wheel (0.30.0)

阿里云的源中 最新版的django-rest-frmework版本为3.7.1

3.6 与 3.7的结构稍有不同. 我之前用3.6, 但是以下对swagger的修改以3.7.1版本为基准. 理解原理之后不同版本只需要稍作修改即可.

第一步修改配置

进入settings.py 文件, 确保INSTALLED_APPS中包含rest_framework


INSTALLED_APPS = [
 'django.contrib.admin',
 'django.contrib.auth',
 'django.contrib.contenttypes',
 'django.contrib.sessions',
 'django.contrib.messages',
 'django.contrib.staticfiles',
 'rest_framework',
 'rest_framework_swagger',
 'mytest',
]

我们导入了三个框架

  • rest_framework

  • rest_framework_swagger

  • mytest (之前的文章中编写简单接口的app)

然后在settings.py 文件中添加以下代码


REST_FRAMEWORK = {
 # 下面这一行表示接口文档的访问权限, AllowAny不做权限限制.
 'DEFAULT_PERMISSION_CLASSES': ('rest_framework.permissions.AllowAny',),
 # 'PAGE_SIZE': 10,
 'PAGINATE_BY':10,
}

SWAGGER_SETTINGS = {
 # 基础样式
 'SECURITY_DEFINITIONS': {
   "basic":{
     'type': 'basic'
   }
 },
 # 如果需要登录才能够查看接口文档, 登录的链接使用restframework自带的.
 'LOGIN_URL': 'rest_framework:login',
 'LOGOUT_URL': 'rest_framework:logout',
 # 'DOC_EXPANSION': None,
 # 'SHOW_REQUEST_HEADERS':True,
 # 'USE_SESSION_AUTH': True,
 # 'DOC_EXPANSION': 'list',
 # 接口文档中方法列表以首字母升序排列
 'APIS_SORTER': 'alpha',
 # 如果支持json提交, 则接口文档中包含json输入框
 'JSON_EDITOR': True,
 # 方法列表字母排序
 'OPERATIONS_SORTER': 'alpha',
 'VALIDATOR_URL': None,
}

第二步编写自定义的swagger接口文档页面.

思路:

之前urls.py中的接口文档页面来自这里


from rest_framework.schemas import get_schema_view

查看源码, 继承schema, 返回schema的子类即可.

接下来编写自己的schema


from rest_framework.permissions import AllowAny
from rest_framework.schemas import SchemaGenerator
from rest_framework.schemas.generators import LinkNode, insert_into
from rest_framework.renderers import *
from rest_framework_swagger import renderers
from rest_framework.response import Response

# from rest_framework.schemas import SchemaGenerator
class MySchemaGenerator(SchemaGenerator):

def get_links(self, request=None):
   # from rest_framework.schemas.generators import LinkNode,
   links = LinkNode()

paths = []
   view_endpoints = []
   for path, method, callback in self.endpoints:
     view = self.create_view(callback, method, request)
     path = self.coerce_path(path, method, view)
     paths.append(path)
     view_endpoints.append((path, method, view))

# Only generate the path prefix for paths that will be included
   if not paths:
     return None
   prefix = self.determine_path_prefix(paths)

for path, method, view in view_endpoints:
     if not self.has_view_permissions(path, method, view):
       continue
     link = view.schema.get_link(path, method, base_url=self.url)
     # 添加下面这一行方便在views编写过程中自定义参数.
     link._fields += self.get_core_fields(view)

subpath = path[len(prefix):]
     keys = self.get_keys(subpath, method, view)

# from rest_framework.schemas.generators import LinkNode, insert_into
     insert_into(links, keys, link)

return links

# 从类中取出我们自定义的参数, 交给swagger 以生成接口文档.
 def get_core_fields(self, view):
   return getattr(view, 'coreapi_fields', ())

class SwaggerSchemaView(APIView):
 _ignore_model_permissions = True
 exclude_from_schema = True

# from rest_framework.permissions import AllowAny
 permission_classes = [AllowAny]
 # from rest_framework_swagger import renderers
 # from rest_framework.renderers import *
 renderer_classes = [
   CoreJSONRenderer,
   renderers.OpenAPIRenderer,
   renderers.SwaggerUIRenderer
 ]

def get(self, request):
   generator = MySchemaGenerator(title='xxxxx',
                  description='''xxxxx''')

schema = generator.get_schema(request=request)

# from rest_framework.response import Response
   return Response(schema)

上面的代码中我加了注释, 写出了需要用到的一些方法, 参数, 类 都是从哪里import进来的.

上面的代码自定义了一个swagger页面, 加入了自定义参数的方法, 设置了访问权限(AllowAny), 添加了title和description,
原理, 其实就是继承父类, 重写方法以覆盖父类中的方法, 修改子类中overwrite的方法以添加我们想要的内容.

上面的代码其实写在哪里都可以, 找得到就行,我一般写在views.py 文件中和其他接口放在一起, 毕竟 http://xxxxx/docs/ 和/api/getjson 这样的接口一样都返回一个视图.

最后一步

修改urls.py文件, 把接口放出去.


from django.conf.urls import url, include
from django.contrib import admin
from rest_framework.schemas import get_schema_view
from mytest.views import ReturnJson
import mytest
# 下面是刚才自定义的schema
from mytest.views import SwaggerSchemaView

urlpatterns = [
 url(r'^admin/', admin.site.urls),
 url(r'^api-auth/', include('rest_framework.urls', namespace='rest_framework')),
 url(r'^docs/', SwaggerSchemaView.as_view(), name='apiDocs'),
 url(r'^api/getjson', ReturnJson.as_view()),
]

注意上面我们添加了两个接口.

api-auth/和docs/

还记得配置文件中的他们吗


'LOGIN_URL': 'rest_framework:login',
'LOGOUT_URL': 'rest_framework:logout',

api-auth/就是为他俩准备的. 因为有时我们需要让接口文档登录之后才能够被看到..

最后运行项目看到

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

剩下的问题

我们的第一个接口没有参数. 向接口文档的getjson接口添加一个参数.

修改 getjson接口对应的views.py文件中的类.ReturnJson类.

添加以下代码


def DocParam(name="default", location="query",
      required=True, description=None, type="string",
      *args, **kwargs):
 return coreapi.Field(name=name, location=location,
            required=required, description=description,
            type=type)

class ReturnJson(APIView):

coreapi_fields=(
   DocParam("token"),
 )

def get(self, request, *args, **kwargs):
   return JsonResponse("Hello world!!!!!!!!++++++中文测试")

这是所有的import


from django.shortcuts import render
from rest_framework.views import APIView
from dss.Serializer import serializer
from django.http import HttpResponse, HttpRequest
from rest_framework.permissions import AllowAny
from rest_framework.schemas import SchemaGenerator
from rest_framework.schemas.generators import LinkNode, insert_into
from rest_framework.renderers import *
from rest_framework_swagger import renderers
from rest_framework.response import Response
# from rest_framework.schemas import *

我也忘了. coreapi.Field是从哪里import的了....

以上代码为 getjson接口添加了token参数.

最终效果.

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

来源:https://www.jianshu.com/p/d7b614b85a74

0
投稿

猜你喜欢

  • 请问鼠标移过去就出现二级菜单代码怎么写啊    <head><style type="tex
  • 比如下面一个listbinfo = ['lao','wang','python']我们通过h
  • digo工具地址:https://github.com/werbenhu/digo特性使用注释中的注解自动代码生成自动检测循环依赖编译时期依
  • 在本篇文章中,我们将介绍回归树及其基本数学原理,并从头开始使用Python实现一个完整的回归树模型。为了简单起见这里将使用递归来创建树节点,
  • 察者模式定义定义了对象之间的一对多依赖,这样一来,当一个对象改变状态时,它的所有依赖都会收到通知并自动更新。观察者模式提供了一种对象设计,让
  • 我以centos 4.4 下面的mysql 5.0.33 手工编译版本为例说明:vi /usr/local/mysql/bin/m
  • 阅读上一篇:请给PNG8一个机会 系列二:对png8的误解Png8的在ie中的怪异表现:1.半透明的png8在ie6以下的浏览器显示为全透明
  • 现在大部分网站都使用asp+access构建,这样的话通过下载access数据库简单就可以对网站进行破坏!  而很多的网站都不太重
  • 问题当浏览SQL Server 2008的新特性时,我们看到了透明数据加密。这看起来很有趣。您能为我们解释一下并介绍下执行它的细节吗?专家解
  • 看过数据库的备份与还原。大多数都是用组件来完成的。其实可通过sql语句来完成。   由于时间关系,未对参数进行验证和界面美化。代码
  • 前端的小伙伴们在babel等的加持下,已经可以愉快的使用es6来写代码了。然后对于服务端的nodejs就有点坑爹了,虽然原生支持了es6,但
  • 继Go 1.18支持泛型后,Go 将在下个版本中支持pdqsort排序算法再次引起了开发者们的热切讨论。目前,Go仓库的最新commit中提
  • 一直以来,ACCESS数据库中的申报数据在分公司与总公司之间传递,用EXCEL或DBASE、TXT甚至ACCESS等格式,我总觉得不太理想。
  • 过去一段时间人们似乎又非常热衷于探讨网络文档的印刷格式,涌现了很多与之相关的技术与理论资料,其中相当重要的一个领域就是关于印刷中字号和行高的
  • 前言最近在开发项目时遇到了发现一个问题,gorm虽然可以自动帮你维护 created_at、updated_at、deleted_at这些关
  • 如果你真正理解Javascript函数是如何调用工作的,那么就可以避免一些bug的发生; 首先让我们创建一个简单的函数,这个函数将在下文中使
  • 当我们建好数据库及表后,首先想到的就是向数据库的表中输入数据.下面我们就来探讨一下如何向数据库增加数据:1.常用的方法是insert语句in
  • 1、图片防盗链在一些大型网站中,比如百度贴吧,该站点的图片采用了防盗链的规则,以至于使用下面代码会发生错误。简单代码:<!DOCTYP
  • 本文实例为大家分享了Python实现图片格式转换的具体代码,供大家参考,具体内容如下碰上这样一个情景:我从网络上下载了一张表情包图片,存放在
  • 这篇文章主要介绍了Python动态声明变量赋值代码实例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋
手机版 网络编程 asp之家 www.aspxhome.com