Django+rest_framework+drf_yasg 生成swaggers在线API文档


Django+rest_framework+drf_yasg 生成swaggers在线API文档
)

背景

最近有了给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

第一步:新建一个Django项目

  • django-admin.py startproject DjangoDrfTest

第二步:新建一个APP

  • python manage.py startapp news

目录结构如下:
在这里插入图片描述

第三步:修改settings.py

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'
        }
    }
}

第四步:修改news/下修改views.py

# -*- 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

第五步:news/下新建urls.py并添加以下内容

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'), 

]

第六步:修改DjangoDrfTest/urls.py

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="contact@snippets.local"),
    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<format>.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<format>.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")),

]

第七步:运行managy.py

  • python manage.py runserver
  • 访问 http://127.0.0.1:8000
  • 效果如下图:
    在这里插入图片描述
  • 看看测试效果:
    在这里插入图片描述
  • Post
  • 在这里插入图片描述
  • 在这里插入图片描述

一些配置项参数与常用场景的说明

  • 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=[]
    )
  • get 方法的参数申明方式
    @swagger_auto_schema(operation_description="partial_update description override",
                         responses={404: 'id not found'},
                         manual_parameters=[test_param])
  • 关于swagger_auto_schema方法的参数详解,请查看方法中的注解

本篇文章,只是简单的讲解了drf_yasg的简单用法,其中的数据是我的测试数据,数据库使用的是mongodb,网上关于使用models与serializers的方法有很多,在此不做叙述,希望本篇文章可以帮助到你。

参考文章

  • 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

代码地址

https://github.com/xubin1993/DjangoDrfTest.git

  • 8
    点赞
  • 41
    收藏
    觉得还不错? 一键收藏
  • 8
    评论
当用户通过Django REST framework进行登录时,服务器会使用Django自带的认证系统验证用户的身份,并生成一个JWT(JSON Web Token)作为用户的身份凭证。JWT是一个加密的字符串,其中包含了用户的身份信息和一些元数据,例如过期时间等。 在使用rest_framework_jwt进行token签发和token续签时,我们可以采用以下流程: 1.安装rest_framework_jwt 在Django项目中安装rest_framework_jwt库,可以使用pip命令进行安装: ``` pip install djangorestframework-jwt ``` 2.在settings.py中配置rest_framework_jwt 在Django项目的settings.py文件中添加rest_framework_jwt相关配置,例如: ``` REST_FRAMEWORK = { 'DEFAULT_AUTHENTICATION_CLASSES': ( 'rest_framework_jwt.authentication.JSONWebTokenAuthentication', 'rest_framework.authentication.SessionAuthentication', 'rest_framework.authentication.BasicAuthentication', ), } JWT_AUTH = { 'JWT_ENCODE_HANDLER': 'rest_framework_jwt.utils.jwt_encode_handler', 'JWT_DECODE_HANDLER': 'rest_framework_jwt.utils.jwt_decode_handler', 'JWT_PAYLOAD_HANDLER': 'rest_framework_jwt.utils.jwt_payload_handler', 'JWT_PAYLOAD_GET_USER_ID_HANDLER': 'rest_framework_jwt.utils.jwt_get_user_id_from_payload_handler', 'JWT_RESPONSE_PAYLOAD_HANDLER': 'rest_framework_jwt.utils.jwt_response_payload_handler', 'JWT_SECRET_KEY': SECRET_KEY, 'JWT_ALGORITHM': 'HS256', 'JWT_VERIFY': True, 'JWT_VERIFY_EXPIRATION': True, 'JWT_LEEWAY': 0, 'JWT_EXPIRATION_DELTA': datetime.timedelta(seconds=300), 'JWT_REFRESH_EXPIRATION_DELTA': datetime.timedelta(days=7), 'JWT_AUTH_HEADER_PREFIX': 'JWT', } ``` 3.生成JWT 在用户认证通过后,可以通过调用rest_framework_jwt库中的jwt_encode_handler()方法生成JWT: ``` from rest_framework_jwt.utils import jwt_encode_handler payload = jwt_payload_handler(user) token = jwt_encode_handler(payload) ``` 其中,jwt_payload_handler()方法用于生成JWT的payload,其中包含了用户的身份信息和一些元数据,例如过期时间等。 4.返回JWT 将生成的JWT返回给客户端,客户端在后续的请求中可以通过HTTP请求头中的Authorization字段携带JWT进行身份验证。 5.续签JWT 当JWT即将过期时,可以通过调用rest_framework_jwt库中的jwt_refresh_handler()方法进行续签: ``` from rest_framework_jwt.utils import jwt_refresh_handler new_token = jwt_refresh_handler(token) ``` 其中,token为即将过期的JWT,new_token为续签后的新JWT。 以上就是使用Django+rest_framework_jwt进行token签发和token续签的具体流程。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值