自定義 drf-yasg 的 Swagger 文檔— 以 GET、POST、檔案上傳為例
簡介如何自訂義 Django REST framework 生成 swagger 的套件 drf-yasg 的文檔。
本篇主要介紹如何自訂義 drf-yasg 的 swagger 文檔,如果對 drf-yasg 不熟悉可以參考此篇:用 Django REST Framework 撰寫 RESTful API 並生成 Swagger 文檔,本篇的 code 可以參考這個 Pull Request。
以下的操作都是會用到 drf_yasg 的裝飾器 swagger_auto_schema,swagger_auto_schema 的功用依照 drf_yasg 的定義為:
Decorate a view method to customize the
Operation
object generated from it.
所以我們需要在預修改的 view.py 引入該裝飾器,就可以準備自定義 Swagger 囉!
from drf_yasg.utils import swagger_auto_schema
一、為 API Operation(如 GET, POST, PATCH, DELETE)加摘要和說明
首先在 API 的 operation 上面加上裝飾器,然後我們就可以設置 swagger_auto_schema
的operation_summary
設置摘要,還有用operation_description
撰寫說明。
@swagger_auto_schema(
operation_summary='我是摘要',
operation_description='我是說明',
)
比方說:
# swagger
from drf_yasg.utils import swagger_auto_schema
from drf_yasg import openapi# other packages
from rest_framework.generics import GenericAPIView
from user.serializers import UserSerializer
class UsersView(GenericAPIView): serializer_class = UserSerializer @swagger_auto_schema(
operation_summary='我是 GET 的摘要',
operation_description='我是 GET 的說明',
)
def get(self, request, *args, **krgs):
略 ... @swagger_auto_schema(
operation_summary='我是 POST 的摘要',
operation_description='我是 POST 的說明',
)
def post(self, request, *args, **krgs):
略 ...
就可以得到下面的結果:
二、為 API Operation(如 GET, POST, PATCH, DELETE)客製化參數
1. 自定義 POST 請求
如果你有用 Serializer,則 drf_yasg 默認會用 serializers.py 定義的 field,比方說我有一個 User 的 model,裡面有 id, email, name 三個 fields:
from django.db import models
class User(models.Model):
id = models.AutoField(auto_created=True, primary_key=True)
email = models.EmailField(unique=True)
name = models.CharField(max_length=100)
因為我在 serializer 寫 field='__all__'
,所以默認在 POST 請求的時候會用除了auto_created 的 id 以外的 field (emial, name)
from user.models import User
from rest_framework import serializers
class UserSerializer(serializers.ModelSerializer):
class Meta:
model = User
fields = '__all__'
如果不希望用 class 的 serializer,可以用 request_body
指定其他 serializer:
@swagger_auto_schema(
operation_summary='我是 POST 的摘要',
request_body=其他 Serializer
)
如果希望自定義參數,比如我只想要用戶填 name,可以將 openapi.Schema
賦值給 request_body
:
@swagger_auto_schema(
operation_summary='我是 POST 的摘要',
request_body=openapi.Schema(
type=openapi.TYPE_OBJECT,
properties={
'name': openapi.Schema(
type=openapi.TYPE_STRING,
description='User Name'
)
}
)
)
就可以達成下面的效果囉:
2. 自定義 GET 請求
如果希望自定義 GET 請求的參數呢?需要用 manual_parameters
,比方說我希望依照 name 查詢 API,就可以這樣寫:
@swagger_auto_schema(
operation_summary='我是 GET 的摘要',
manual_parameters=[
openapi.Parameter(
name='name',
in_=openapi.IN_QUERY,
description='User Name',
type=openapi.TYPE_STRING
)
]
)
說明一下參數的意義:
name
:參數名
in_
:表示參數位於 request 的哪,比如:
openapi.IN_BODY
,參數在 request 的 body,例如 POST 請求。openapi.IN_QUERY
,參數在 request 的 quey,例如 user/?name=123。openapi.IN_FORM
,參數在 request 的 form 表單,例如檔案上傳。openapi.IN_PATH
,參數在 request 的 path,比方說 /user/<id>/
type
:參數的型別,如:openapi.TYPE_STRING
、openapi.TYPE_NUMBER
、openapi.TYPE_INTEGER
、openapi.TYPE_BOOLEAN
、openapi.TYPE_ARRAY
、openapi.TYPE_FILE
等,更多資訊可參考官方文檔。
2. 自定義 Form 表單請求
Form 表單稍微複雜一點,需要指定 View 的 parser_class為 FormParser
如果還有其他參數要一起提交,則要加上MultiPartParser
不然會有以下錯誤:
Unsupported media type \”multipart/form-data; boundary= — — WebKitFormBoundaryU5zgTtpr7NV7zNFt\” in request.”
所以要改成:
from rest_framework.parsers import (
FormParser,
MultiPartParser
)其他 packages 略 ...
class UsersView(GenericAPIView): parser_classes = (FormParser, MultiPartParser) @swagger_auto_schema(
operation_summary='我是 POST 的摘要',
operation_description='我是 POST 的說明',
manual_parameters=[
openapi.Parameter(
name='image',
in_=openapi.IN_FORM,
description='Image',
type=openapi.TYPE_FILE
),
]
)
def post(self, request, *args, **krgs):
略...
就可以達到下面結果囉!
等等那個 email 跟 name 是怎麼肥事??原因是會默認拿 Serializer 的 field QQ 如果這些參數不需要用戶填寫可考慮設 readonly。
三、API 已棄用
如果要標註某些 API 已棄用,只需要加上 depracated=True
即可,如:
class UsersView(GenericAPIView): @swagger_auto_schema(
operation_summary='我是 POST 的摘要',
operation_description='我是 POST 的說明',
depracated=True
)
def post(self, request, *args, **krgs):
略...
就有下面的效果:
以上是如何自訂義 Django REST framework 生成 swagger 的套件 drf-yasg 的文檔的簡介,感謝閱讀。