django-rest-swagger
前提工作
1 2 | pip3 install - - user django> = 2.0 . 0 pip3 install - - user django - rest - swagger |
安装完成之后,创建一个django项目
第一步:修改setting配置如下
1 2 3 4 5 | INSTALLED_APPS = [ 'app.apps.AppConfig' , 'rest_framework' , 'rest_framework_swagger' , ] |
并新增
1 2 3 4 5 6 7 | SWAGGER_SETTINGS = { # 基础样式 'SECURITY_DEFINITIONS' : { "basic" :{ 'type' : 'basic' } }, |
# 如果需要登录才能够查看接口文档, 登录的链接使用restframework自带的.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | '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
具体如
1 2 3 4 | from django.conf.urls import url,include from django.contrib import admin from rest_framework import routers from app import views |
# 路由
1 2 3 | router = routers.DefaultRouter() router.register(r 'users' ,views.UserViewSet,base_name = 'user' ) router.register(r 'groups' ,views.GroupViewSet,base_name = 'group' ) |
# 重要的是如下三行
1 2 3 | from rest_framework.schemas import get_schema_view from rest_framework_swagger.renderers import SwaggerUIRenderer, OpenAPIRenderer schema_view = get_schema_view(title = 'Users API' , renderer_classes = [OpenAPIRenderer, SwaggerUIRenderer]) |
1 2 3 4 5 6 | urlpatterns = [ # swagger接口文档路由 # url(r'^docs/', schema_view, name="docs"), 注:此条docs用到上面的router url(r '^docs/' , views.SwaggerSchemaView.as_view(), name = 'apiDocs' ), # 此条是自定义,本篇主要使用此条 url(r '^admin/' , admin.site.urls), url(r '^' ,include(router.urls)), |
# drf登录
1 2 3 | url(r '^api-auth/' ,include( 'rest_framework.urls' ,namespace = 'rest_framework' )), url(r '^api/getjson' , views.ReturnJson.as_view()), ] |
查看源码, 继承schema, 返回schema的子类即可.
接下来编写自己的schema,可以重新起一个文件名。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 | from django.http import HttpResponse, JsonResponse from django.contrib.auth.models import User,Group from rest_framework import viewsets from app.serializer import UserSerializer,GroupSerializer from rest_framework.response import Response from .serializer import UserBaseSerializer 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 CoreJSONRenderer from rest_framework_swagger import renderers from rest_framework.views import APIView import coreapi from django.http import QueryDict from rest_framework.request import Request 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) |
然后启动
上面的代码自定义了一个swagger页面, 加入了自定义参数的方法, 设置了访问权限(AllowAny), 添加了title和description,
原理, 其实就是继承父类, 重写方法以覆盖父类中的方法, 修改子类中overwrite的方法以添加我们想要的内容.
上面的代码其实写在哪里都可以, 找得到就行,我一般写在views.py 文件中和其他接口放在一起, 毕竟 http://xxxxx/docs/ 和/api/getjson 这样的接口一样都返回一个视图.
需要注意的是一般用的是docs,而api-auth/就是为'LOGIN_URL': 'rest_framework:login','LOGOUT_URL': 'rest_framework:logout'准备的. 因为有时我们需要让接口文档登录之后才能够被看到。
一切准备就绪,接下来就开始自定义接口文档了。在上面的urls.py中的 api/getjson就是,然后开始编写。可以和上面的schema放在一个文件夹里,个人习惯放在一起
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 | # Create your views here. # class UserViewSet(viewsets.ModelViewSet): # '''查看,编辑用户的界面''' # queryset = User.objects.all().order_by('-date_joined') # serializer_class = UserSerializer # # class GroupViewSet(viewsets.ModelViewSet): # '''查看,编辑组的界面''' # queryset = Group # serializer_class = GroupSerializer 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 ) def get_parameter_dic(request, * args, * * kwargs): # 处理自定义接口传过来的参数值 if isinstance (request, Request) = = False : return {} query_params = request.query_params if isinstance (query_params, QueryDict): query_params = query_params. dict () result_data = request.data if isinstance (result_data, QueryDict): r esult_data = result_data. dict () if query_params ! = {}: query_params else : return result_data class ReturnJson(APIView): coreapi_fields = ( DocParam( "token" ), DocParam( 'id' ), ) def get( self , request, * args, * * kwargs): params = get_parameter_dic(request) print (params) return JsonResponse(data = params) def post( self , request, * args, * * kwargs): params = get_parameter_dic(request) return JsonResponse(data = params) def put( self , request, * args, * * kwargs): params = get_parameter_dic(request) return JsonResponse(data = params) |
然后重启,请求访问测试结果如图。
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步