最近有了给API平台自动生成接口文档的需求,但是我们的API平台没有使用Django的models,而且代码结构也不想做大的改动。经过调研,最后决定采用Django+rest_framework+drf_yasg的方法,最后实现出来很简单。但调研过程中因为自己对Django体系的不熟悉,网上很多文档又没有系统的描述在不使用models与serializers的情况下,如何使用swaggers生成文档,特别是API参数如何在文档中生自动显示,在文档界面如何给API传参等问题,并没有具体的描述(也有可能是我没有找到,或者没有看懂)
from drf_yasg.utils import swagger_auto_schema
@swagger_auto_schema
python:2.7.13
Django==1.11.16
drf-yasg==1.11.0
djangorestframework==3.7.7
user_agents==1.1.0
swagger-spec-validator==2.1.0
flex==6.11.1
django-cors-headers==2.1.0
如果还缺什么包,可以参考:https://github.com/axnsan12/drf-yasg/tree/master/requirements
中:base.txt,testproj.txt,validation.txt
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
"news",
#"corsheaders",
'rest_framework',
"drf_yasg"
]
SWAGGER_SETTINGS = {
'LOGIN_URL': '/admin/login',
'LOGOUT_URL': '/admin/logout',
'PERSIST_AUTH': True,
'REFETCH_SCHEMA_WITH_AUTH': True,
'REFETCH_SCHEMA_ON_LOGOUT': True,
'DEFAULT_INFO': 'DjangoDrfTest.urls.swagger_info',#这里注意,更改DjangoDrfTest
'SECURITY_DEFINITIONS': {
'Basic': {
'type': 'basic'
},
'Bearer': {
'type': 'apiKey',
'name': 'authorization',
'in': 'header'
},
'Query': {
'type': 'apiKey',
'name': 'auth',
'in': 'query'
}
}
}
# -*- coding: utf-8 -*-
import sys
reload(sys)
sys.setdefaultencoding("utf8")
sys.path.append('../')
# from __future__ import unicode_literals
from django.shortcuts import render
from drf_yasg.utils import swagger_auto_schema
from drf_yasg import openapi
from rest_framework.views import APIView
import json
from django.http import JsonResponse
from pymongo import MongoClient
conn = MongoClient(host='192.168.*****', port=*****)
# 连接数据库
db = conn['test']
table = db['data']
def get_request_args(func):
def _get_request_args(self, request):
if request.method == 'GET':
args = request.GET
else:
body = request.body
if body:
try:
args = json.loads(body)
except Exception as e:
print e
# return makeJsonResponse(status=StatusCode.EXECUTE_FAIL, message=str(e))
args = request.POST
else:
args = request.POST
return func(self, request, args)
return _get_request_args
# Create your views here.
class GetOneNews(APIView):
'''
list:
Return one news
'''
test_param = openapi.Parameter("id", openapi.IN_QUERY, description="test manual param",
type=openapi.TYPE_INTEGER)
@swagger_auto_schema(operation_description="partial_update description override",
responses={404: 'id not found'},
manual_parameters=[test_param])
@get_request_args
def get(self, request, args):
data = []
id = args.get("id")
i = table.find_one({"_id": int(id)})
data.append({'user_name': i.get("user_name"), "content": i.get("content")})
return JsonResponse({"data": data})
@swagger_auto_schema(
operation_description="apiview post description override",
request_body=openapi.Schema(
type=openapi.TYPE_OBJECT,
required=['id', "user_name"],
properties={
'id': openapi.Schema(type=openapi.TYPE_INTEGER),
'user_name': openapi.Schema(type=openapi.TYPE_STRING)
},
),
security=[]
)
@get_request_args
def post(self, request, args):
data = []
id = args.get("id")
user_name = args.get("user_name")
i = table.find_one({"_id": int(id)})
data.append({'user_name': i.get("user_name"), "content": i.get("content")})
return JsonResponse({"data": data})
pass
import sys
reload(sys)
sys.setdefaultencoding('utf-8')
sys.path.append('../')
from django.conf.urls import url
from views import *
urlpatterns = [
url(r'^getOneNews/?$', GetOneNews.as_view(), name='get_one_news'),
]
import user_agents
from django.conf.urls import include, url
from django.contrib import admin
from django.shortcuts import redirect
from rest_framework import permissions
from drf_yasg import openapi
from drf_yasg.views import get_schema_view
swagger_info = openapi.Info(
title="Snippets API",
default_version='v1',
description="""This is a demo project for the [drf-yasg](https://github.com/axnsan12/drf-yasg) Django Rest Framework library.
The `swagger-ui` view can be found [here](/cached/swagger).
The `ReDoc` view can be found [here](/cached/redoc).
The swagger YAML document can be found [here](/cached/swagger.yaml).
You can log in using the pre-existing `admin` user with password `passwordadmin`.""", # noqa
terms_of_service="https://www.google.com/policies/terms/",
contact=openapi.Contact(email="[email protected]"),
license=openapi.License(name="BSD License"),
)
SchemaView = get_schema_view(
validators=['ssv', 'flex'],
public=True,
permission_classes=(permissions.AllowAny,),
)
def root_redirect(request):
user_agent_string = request.META.get('HTTP_USER_AGENT', '')
user_agent = user_agents.parse(user_agent_string)
if user_agent.is_mobile:
schema_view = 'cschema-redoc'
else:
schema_view = 'cschema-swagger-ui'
return redirect(schema_view, permanent=True)
urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'^swagger(?P.json|.yaml)$' , SchemaView.without_ui(cache_timeout=0), name='schema-json'),
url(r'^swagger/$', SchemaView.with_ui('swagger', cache_timeout=0), name='schema-swagger-ui'),
url(r'^redoc/$', SchemaView.with_ui('redoc', cache_timeout=0), name='schema-redoc'),
url(r'^redoc-old/$', SchemaView.with_ui('redoc-old', cache_timeout=0), name='schema-redoc-old'),
url(r'^cached/swagger(?P.json|.yaml)$' , SchemaView.without_ui(cache_timeout=None), name='cschema-json'),
url(r'^cached/swagger/$', SchemaView.with_ui('swagger', cache_timeout=None), name='cschema-swagger-ui'),
url(r'^cached/redoc/$', SchemaView.with_ui('redoc', cache_timeout=None), name='cschema-redoc'),
url(r'^$', root_redirect),
url(r'^news/', include('news.urls', namespace="crawl_config")),
]
API通过header apiKey验证或者apiKey在query中,变量的配置位置在settings.py中SWAGGER_SETTINGS配置项中:
@swagger_auto_schema 装饰器要放在所有装饰器的首位
post方法的参数申明方式:
swagger_auto_schema(
operation_description="apiview post description override",
request_body=openapi.Schema(
type=openapi.TYPE_OBJECT,
required=['id', "user_name"],
properties={
'id': openapi.Schema(type=openapi.TYPE_INTEGER),
'user_name': openapi.Schema(type=openapi.TYPE_STRING)
},
),
security=[]
)
@swagger_auto_schema(operation_description="partial_update description override",
responses={404: 'id not found'},
manual_parameters=[test_param])
https://blog.csdn.net/lmz_lmz/article/details/81028715
https://blog.csdn.net/weixin_31449201/article/details/81109128
https://github.com/axnsan12/drf-yasg
https://drf-yasg.readthedocs.io/en/stable/readme.html
https://blog.csdn.net/wang785994599/article/details/80799142