Backend - Django Swagger

发布于:2024-04-19 ⋅ 阅读:(27) ⋅ 点赞:(0)

目录

一、安装依赖

二、配置环境

三、路由(urls)

四、swagger UI 界面

(一)UI 界面

(二)单引号问题:Expecting property name enclosed in double quotes

1. 原因

2. 解决

五、自定义swagger文档

(一)装饰器 @swagger_auto_schema

1. 属性认知

2. manual_parameters属性

(1)name:参数名

(2)in_:参数位于 request 的 某个位置

(3)type:参数类型

 (二)应用

1. 导入依赖

2. 自定义openapi.Parameter参数

3. 自定义openapi.Schema参数

4. 自定义openapi.Response参数

5. views内容 

六、API被弃用


一、安装依赖

pip install drf-yasg==1.21.5

二、配置环境

# settings.py文件中
INSTALLED_APPS = [
    ...
    'drf_yasg',  # 注意是drf_yasg,而不是drf-yasg
    ...
]

三、路由(urls)

from django.urls import path, re_path  # url规则
from rest_framework import permissions   # API的访问权限
from drf_yasg.views import get_schema_view
from drf_yasg import openapi
from myBook import views as book_view

# 基础设置
schema_view = get_schema_view(
	openapi.Info(
		title="Books API",
		default_version='v1',
		description="Books' RESTful API documentation.",
		terms_of_service="https://www.google.com/policies/terms/",
		contact=openapi.Contact(email="XXX"),
		license=openapi.License(name="BSD License"),
	),
	public=True,
	permission_classes=[permissions.AllowAny],
)

# 补充swagger路由
urlpatterns += [
	re_path(r'^swagger(?P<format>\.json|\.yaml)$', schema_view.without_ui(cache_timeout=0), name='schema-json'),
	re_path(r'^swagger/$', schema_view.with_ui('swagger', cache_timeout=0), name='schema-swagger-ui'),
	re_path(r'^redoc/$', schema_view.with_ui('redoc', cache_timeout=0), name='schema-redoc'),
]

四、swagger UI 界面

(一)UI 界面

        浏览器输入swagger UI 的链接: http://127.0.0.1:8000/swagger/

        注意:

        1. 链接XXX/swagger尾巴,还有后缀“/”。

        2. 只要符合restful API序列化类写法的对应路由,就会呈现在swagger UI界面上。

针对Django 序列化,可参考另一篇文章:Backend - DRF 序列化(django-rest-framework)-CSDN博客    

(二)单引号问题:Expecting property name enclosed in double quotes

1. 原因

        swagger UI界面中,字典里的引号都得用双引号,而不是单引号。

2. 解决

        python代码里,将单引号替换成双引号。

import json 
my_str.replace("\'", "\"")
my_dict = json.loads(my_str)

五、自定义swagger文档

(一)装饰器 @swagger_auto_schema

1. 属性认知

        以get方法的@swagger_auto_schema装饰器为例,一般情况下有operation_summary、operation_description、manual_parameters、responses等属性。

# 所需依赖
from rest_framework import status  # Django REST Framework
from drf_yasg import openapi  # Swagger
from drf_yasg.utils import swagger_auto_schema  # Swagger
@swagger_auto_schema(
		operation_summary='GET 概括', 
		operation_description='GET 描述',
		manual_parameters=[
			openapi.Parameter(
				name='bookname',  # name是用来确定唯一值的(不能重复)
				description='这是描述',
				in_=openapi.IN_QUERY,
				type=openapi.TYPE_STRING,
				required=True,
			)
		],
		responses={
			status.HTTP_200_OK: openapi.Response(
				description='Success',
				schema=openapi.Schema(
					type=openapi.TYPE_OBJECT,
					properties={
						'result':  openapi.Schema(type=openapi.TYPE_BOOLEAN, description='successful!'),
						'resData': openapi.Schema(
												type=openapi.TYPE_ARRAY, 
												items=openapi.Schema(
													type=openapi.TYPE_OBJECT, 
													description='该列表的items是个dict,分别有key值为key1和key2', 
													properties={'key1': openapi.Schema(type=openapi.TYPE_INTEGER, description='第一个值'),
																'key2': openapi.Schema(type=openapi.TYPE_STRING, description='第二个值'),}
												),
									),
					},
				),
			),
			status.HTTP_401_UNAUTHORIZED: openapi.Response(
				description='Unauthorized',
				schema=openapi.Schema(
									type=openapi.TYPE_OBJECT,
									properties={'result': openapi.Schema(type=openapi.TYPE_BOOLEAN, description='HTTP 401 UNAUTHORIZED.')}
						),
			),
		},
	)

2. manual_parameters属性

主要参数有name、in_、type。

(1)name:参数名
(2)in_:参数位于 request 的 某个位置

        其中,openapi.IN_BODY ,参数在 request 的 body,例如 POST 请求。

        openapi.IN_QUERY ,参数在 request 的 quey,例如 user/?authorname='萝卜干'  。

        openapi.IN_FORM ,参数在 request 的 form 表单。

        openapi.IN_PATH ,参数在 request 的 path,例如 /user/<id>/。

(3)type:参数类型

        如:openapi.TYPE_NUMBER,类型为 number。

        openapi.TYPE_STRING,类型为 string。

        openapi.TYPE_BOOLEAN,类型为 boolean。

        openapi.TYPE_FILE,类型为 file。

 (二)应用

        以下内容都写在同一个views.py中。

1. 导入依赖

from myApp import myserializer
from myApp.myserializer import AuthorApi
from drf_yasg import openapi  # Swagger
from drf_yasg.utils import swagger_auto_schema  # Swagger
from rest_framework.generics import GenericAPIView  # Django REST Framework
from rest_framework import status  # Django REST Framework

2. 自定义openapi.Parameter参数

class manualParam:
        my_str = openapi.Parameter(
            name='bookname',  # name是用来确定唯一值的(不能重复)
            description='这是描述',
            in_=openapi.IN_QUERY,
            type=openapi.TYPE_STRING,
            required=True,
        )
        my_num = openapi.Parameter(
            name='authorname',
            description='这是描述',
            in_=openapi.IN_QUERY,
            type=openapi.TYPE_NUMBER,
            required=False,
        )

3. 自定义openapi.Schema参数

    class manualRes:
        res200 = openapi.Schema(type=openapi.TYPE_BOOLEAN, description='successful!')
        res401 = openapi.Schema(type=openapi.TYPE_BOOLEAN, description='HTTP 401 UNAUTHORIZED.')
        books_properties ={'key1': openapi.Schema(type=openapi.TYPE_INTEGER, description='第一个值'),'key2': openapi.Schema(type=openapi.TYPE_STRING, description='第二个值'),}
        resData = openapi.Schema(
                    type=openapi.TYPE_ARRAY, 
                    items=openapi.Schema(type=openapi.TYPE_OBJECT, description='该列表的items是个dict,分别有key值为key1和key2', properties=books_properties ),
                )

4. 自定义openapi.Response参数

# 和“(3)自定义openapi.Schema参数”在同一个类中
class manualRes:
    # Success 成功 200
    response_200 = openapi.Response(
                description='Success',
                schema=openapi.Schema(
                    type=openapi.TYPE_OBJECT,
                    properties={
                        'result': res200,
                        'resData': resData,
                    },
                ),
            )
 
    # Unauthorized 无权限 401 
    response_401 = openapi.Response(
        description='Unauthorized',
        schema=openapi.Schema(type=openapi.TYPE_OBJECT,properties={'result': res401}),
    )

5. views内容 

    class Book(GenericAPIView):
        @swagger_auto_schema(
            operation_summary='该 get 的概括', 
            operation_description='该 get 的描述', 
            manual_parameters=[
                manualParam.my_str,
                manualParam.my_num
            ],
            responses={
                status.HTTP_200_OK: manualRes.response_200,
                status.HTTP_401_UNAUTHORIZED: manualRes.response_401,
            },
        )
        def get(self, request, *args, **kwargs):
            try:
                reqdata = request.data
                res = AuthorApi(data=reqdata) # 使用序列化器
            except Exception as e:
                pass
            return JsonResponse()
        @swagger_auto_schema(
            operation_summary='该 post 的概括', operation_description='该 post 的描述', request_body=myserializer.SerializerBookCreate,
        )
        def post(self, request, *args, **kwargs):
            try:
                pass
            except Exception as e:
                pass
            return JsonResponse()
        @swagger_auto_schema(
            operation_summary='该 delete 的概括', operation_description='该 delete 的描述', request_body=myserializer.SerializerBookDelete,
        )
        def delete(self, request, *args, **kwargs):
            try:
                pass
            except Exception as e:
                pass
            return JsonResponse()
        @swagger_auto_schema(
            operation_summary='该 patch 的概括', operation_description='该 patch 的描述', request_body=myserializer.SerializerBookPatch,
        )
        def patch(self, request, *args, **kwargs):
            try:
                pass
            except Exception as e:
                pass
            return JsonResponse()

六、API被弃用

若想提示某API已被弃用,则设置 depracated=True。

例如:

@swagger_auto_schema(
    operation_summary='该 post 的概括',
    operation_description='该 post 的描述',
    depracated=True 
)