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/就是为他俩准备的. 因为有时我们需要让接口文档登录之后才能够被看到..

最后运行项目看到

剩下的问题

我们的第一个接口没有参数. 向接口文档的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参数.

最终效果.

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • Django 开发环境配置过程详解

    开发环境 开发环境为: Win 10(64位) Python 3.7.0 Django 2.1 安装Python python的安装为比较简单,首先找到Python官方网站,选择python3.7的windows版本,下载并安装. 安装时注意勾选添加python到环境变量中.如果没有或者漏掉这一步,请安装完毕后自行添加. 若实在不知道怎么弄的,看这篇文章: windows上安装python3教程以及环境变量配置 安装完成后打开命令行,输入python -V,系统打印出python的版本号,说明安

  • Django 实现图片上传和显示过程详解

    第1章 新建工程和创建app 新建工程和创建app就不用贴出来了,我这里是测试图片上传的功能能否实现,所以项目都是新的,正常在以有的app下就可以 第2章 模型层: 2.1创建数据库 from django.dbimport models # Create your models here. class User(models.Model): name= models.CharField(max_length=50) # upload_to 指定上传文件位置 # 这里指定存放在img/ 目录下

  • django 捕获异常和日志系统过程详解

    这一块的内容很少, 异常使用try except即可, 日志只需要几行配置. 使用装饰器捕获方法内的所有异常 我使用装饰器来整个包裹一个方法, 捕获方法中的所有异常信息.并将其转为json返回客户端. import functools def catch_exception(func, code=500, *args, **kwargs): ''' :param func: :return: ''' @functools.wraps(func, *args, **kwargs) def nefe

  • 使用django实现一个代码发布系统

    一 前期说明: 我运行项目的环境是nginx+php,存储代码用的是gitlab, python版本:3.6 django版本:2.2.1 mysql版本:5.7 二 大体思路 1 需要知道主机的用户名,密码,端口号, 2 需要知道gitlab的用户名和密码 3 我准备把上面两条的信息,存储到当前登录用户的session中. 三实现功能 1 针对单个主机发布和回滚代码 2 可以批量发布和回滚代码 3角色分为管理员,开发,运维,测试,产品几个角色,每个角色返回不同的页面,利用rbac基于角色去实现

  • django 2.2和mysql使用的常见问题

    可能是由于Django使用的MySQLdb库对Python3不支持,我们用采用了PyMySQL库来代替,导致出现各种坑,特别是执行以下2条命令的是时候: python manage.py makemigrations or python manage.py inspectdb 第一个坑(提示你的mysqlclient版本过低) 无聊你是否执行pip install mysqlclient安装的最新版的,都抛出: django.core.exceptions.ImproperlyConfigure

  • 解决Django中多条件查询的问题

    tags: django中对条件查询 一些cms项目都会使用到多条件查询,我们后端如何处理请求的条件呢? 满足一个条件 满足两个条件 满足多个条件 -------. 这样处理起来会非常的恼火. 其实有多方法比如(传参数,传字典,传Q对象,传F对象-)陷入深深的思考中-怎么用做简单的方法把这个需求解决了. 个人觉得.把我们的查询的所有条件来构建一个字典来查询起来比较高效.具体如何操作见下面的代码: 视图函数. def order_list(request): if request.method =

  • django框架使用方法详解

    我的文章的意义 服务端开发,python,django这些内容上面的链接中有详细的阐述. 我写的内容肯定没有上面的完备,准确. 我的文章的价值在于从一个iOS程序员的角度来理解服务端开发. 客户端程序员在学习服务端开发时可能会有一些知识盲点. 我遇到的知识盲点我会着重介绍. 环境 操作系统 macOS Sierra 10.12.6 IDE PyCharm python 3.5 创建django项目 首先 创建一个空白环境 mkvirtualenv -p /usr/local/bin/python

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

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

  • Django加载配置的过程详解

    目录 一. Django服务启动 manage.py 二. 引入配置 三. 加载配置 一. Django服务启动 manage.py os.environ.setdefault("DJANGO_SETTINGS_MODULE", "ui.settings") 设置配置文件环境变量- #!/usr/bin/env python import os import sys if __name__ == "__main__": os.environ.se

  • Django REST framework 视图和路由详解

    DRF中的Request 在Django REST Framework中内置的Request类扩展了Django中的Request类,实现了很多方便的功能--如请求数据解析和认证等. 比如,区别于Django中的request从request.GET中获取URL参数,从request.POST中取某些情况下的POST数据. 在APIView中封装的request,就实现了请求数据的解析: 对于GET请求的参数我们通过request.query_params来获取. 对于POST请求.PUT请求的

  • Django models.py应用实现过程详解

    编写 models.py 文件 from django.db import models # Create your models here. class User_info(models.Model): username = models.CharField(max_length=25,verbose_name='用户名') password = models.CharField(max_length=25,verbose_name='密码') age = models.IntegerFiel

  • Django 通过JS实现ajax过程详解

    ajax的优缺点 AJAX使用Javascript技术向服务器发送异步请求 AJAX无须刷新整个页面 因为服务器响应内容不再是整个页面,而是页面中的局部,所以AJAX性能高 小练习:计算两个数的和 方式一:这里没有指定contentType:默认是urlencode的方式发的 index.html <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8">

  • Django 源码WSGI剖析过程详解

    前言 python 作为一种脚本语言, 已经逐渐大量用于 web 后台开发中, 而基于 python 的 web 应用程序框架也越来越多, Bottle, Django, Flask 等等. 在一个 HTTP 请求到达服务器时, 服务器接收并调用 web 应用程序解析请求, 产生响应数据并返回给服务器. 这里涉及了两个方面的东西: 服务器(server)和应用程序(application). 势必要有一个合约要求服务器和应用程序都去遵守, 如此按照此合约开发的无论是服务器还是应用程序都会具有较大

  • Android开发vsts agent支持自定义task过程详解

    vsts 中支持自定义Build/Release的过程Task 目标:做一个可以读取 Xamarin.Android 所生成的 APK 的 基本信息的 task ,包括 package(包名) / application label(应用标题 )/version name(版本号)/version code(版本代码) 下面简述流程 1.下载并安装 Visual Studio Code(http://code.visualstudio.com ),当然使用 Visual Studio 或者其它任

  • Django实现跨域请求过程详解

    前言 CORS 即 Cross Origin Resource Sharing 跨域资源共享. 跨域请求分两种:简单请求.复杂请求. 简单请求 简单请求必须满足下述条件. HTTP方法为这三种方法之一:HEAD.GET.POST HTTP头消息不超出以下字段: Accept.Accept-Language.Content-Language.Last-Event-ID 且Content-Type只能为下列类型中的某一个: application/x-www-from-urlencoded mult

  • Python Django 实现简单注册功能过程详解

    项目创建略,可参考Python Django Vue 项目创建. 目录结构如下 编辑views.py from django.shortcuts import render # Create your views here. from django.http import HttpResponse from django.shortcuts import render from common.DBHandle import DataBaseHandle import time def djang

随机推荐