您好,登錄后才能下訂單哦!
前言
之前的文章編寫了一個返回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', ]
我們導入了三個框架
然后在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參數.
最終效果.
以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持億速云。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。