前言
之前的文章编写了一个返回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/就是为他俩准备的. 因为有时我们需要让接口文档登录之后才能够被看到..
最后运行项目看到
剩下的问题
我们的第一个接口没有参数. 向接口文档的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参数.
最终效果.
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。
《魔兽世界》大逃杀!60人新游玩模式《强袭风暴》3月21日上线
暴雪近日发布了《魔兽世界》10.2.6 更新内容,新游玩模式《强袭风暴》即将于3月21 日在亚服上线,届时玩家将前往阿拉希高地展开一场 60 人大逃杀对战。
艾泽拉斯的冒险者已经征服了艾泽拉斯的大地及遥远的彼岸。他们在对抗世界上最致命的敌人时展现出过人的手腕,并且成功阻止终结宇宙等级的威胁。当他们在为即将于《魔兽世界》资料片《地心之战》中来袭的萨拉塔斯势力做战斗准备时,他们还需要在熟悉的阿拉希高地面对一个全新的敌人──那就是彼此。在《巨龙崛起》10.2.6 更新的《强袭风暴》中,玩家将会进入一个全新的海盗主题大逃杀式限时活动,其中包含极高的风险和史诗级的奖励。
《强袭风暴》不是普通的战场,作为一个独立于主游戏之外的活动,玩家可以用大逃杀的风格来体验《魔兽世界》,不分职业、不分装备(除了你在赛局中捡到的),光是技巧和战略的强弱之分就能决定出谁才是能坚持到最后的赢家。本次活动将会开放单人和双人模式,玩家在加入海盗主题的预赛大厅区域前,可以从强袭风暴角色画面新增好友。游玩游戏将可以累计名望轨迹,《巨龙崛起》和《魔兽世界:巫妖王之怒 经典版》的玩家都可以获得奖励。
更新动态
- 群星.1999-上华世纪国语总冠军4CD【上华】【WAV+CUE】
- 叶丽仪.1992-仙鹤神针电视剧原声音乐专辑【星传真】【WAV+CUE】
- 陈柏宇.2011-QUINQUENNIUM【SONY】【WAV+CUE】
- 《51首热门当红歌曲 十大顶级发烧女声 3CD》[WAV+CUE][1.6GB]
- 《赵传 深受摇滚迷青睐的台湾音乐人 约定》[WAV+CUE][320MB]
- 《庄心妍 实力唱将 发烧音乐精选集》[WAV+CUE][380MB]
- [音展纪念碟]2006年《TAA台湾第十六届国际HI-ENDHI-FI音响展》2cd[WAV]
- 中国音乐地图之听见西藏山歌牧歌酒歌2020[WAV分轨]
- 王宏伟2017-永远的红飘带[太平洋影音][WAV+CUE]
- 费翔.1997-NOW现在【第一中国】【WAV+CUE】
- 新格合唱团.1981-我唱你和2辑(滚石新格民歌系列)【新格】【WAV+CUE】
- 陈柏宇.2011-QUINQUENNIUM【SONY】【WAV+CUE】
- 雨果唱片-《金唛系列-蔷薇依韵琼瑶》WAV
- 陈百强《凝望(2012华纳LPCD45限量版)[DMI]》[WAV整轨]
- 模拟之声慢刻CD《徐小凤45周年》[德国母带][低速原抓WAV+CUE]