Django實現統一包裝接口返回值數據格式
- 2022 年 4 月 4 日
- 筆記
- Python / Django
前言
最近實在太忙了,開始了一個新的項目,為了快速形成產品,我選擇了Django來實現後端,然後又拿起了之前我封裝了項目腳手架「DjangoStarter」。
由於前段時間我寫了不少.NetCore的後端代碼,對CRUD的接口開發又有了一些新的理解,所以肯定也要把DjangoStarter改造一番,改得更加順手~
題外話:話說我在前端終於真正用上react,不得不說 ts + react 真好用,「前端帶師」的安利可真不錯啊(妙啊
正題
準確來講是搭配DjangoRestFramework
來實現的,核心代碼分為兩部分,一個是錯誤處理包裝,一個是響應包裝renderer
。
無論請求是否報錯,都會被我們自定義的renderer
包裝。
代碼
開始上代碼吧~
首先在項目里添加一個新的Python包,位置根據情況自行安排,我在DjangoStarter
模板中的位置是utils/response
,接下來的兩個文件都會放在這個目錄中
第一個是錯誤處理的exception.py
文件代碼
from typing import Dict
from rest_framework.exceptions import ValidationError
from rest_framework.views import exception_handler
from rest_framework.views import Response
from rest_framework.utils.serializer_helpers import ReturnDict
from rest_framework import status
def custom_handler(err: ValidationError, context: dict):
# 先調用REST framework默認的異常處理方法獲得標準錯誤響應對象
response: Response = exception_handler(err, context)
if response is None:
return Response({
'message': f'服務器錯誤:{err}'
}, status=status.HTTP_500_INTERNAL_SERVER_ERROR, exception=True)
else:
res = {'message': response.reason_phrase}
res.update(response.data)
return Response(res, status=response.status_code, exception=True)
然後是自定義renderer.py
代碼:
from rest_framework.renderers import JSONRenderer
class CustomRenderer(JSONRenderer):
# 重構render方法
def render(self, data, accepted_media_type=None, renderer_context=None):
if renderer_context:
# 響應的信息,成功和錯誤的都是這個
# 成功和異常響應的信息,異常信息在前面自定義異常處理中已經處理為{'message': 'error'}這種格式
# 如果返回的data為字典
if isinstance(data, dict):
# 響應信息中有message和code這兩個key,則獲取響應信息中的message和code,並且將原本data中的這兩個key刪除,放在自定義響應信息里
# 響應信息中沒有則將msg內容改為請求成功 code改為請求的狀態碼
msg = data.pop('message', '請求成功')
code = data.pop('code', renderer_context["response"].status_code)
# 如果不是字典則將msg內容改為請求成功 code改為響應的狀態碼
else:
msg = '請求成功'
code = renderer_context["response"].status_code
# 自定義返回的格式
ret = {
'message': msg,
'code': code,
'data': data,
}
# 返回JSON數據
return super().render(ret, accepted_media_type, renderer_context)
else:
return super().render(data, accepted_media_type, renderer_context)
關鍵的地方都注釋了,很容易看懂
包裝出來每個接口的返回值就都是這個樣子
{
"message": "msg",
"code": 200,
"data": {
"data1": "123"
}
}
配置
為了讓上面的代碼發揮作用,還得配置一下RestFramework
編輯settings.py
文件,在REST_FRAMEWORK
節點添加這兩個配置,注意路徑要和前面兩個文件的路徑一致。這裡我是以DjangoStarter
項目為例。
REST_FRAMEWORK = {
# 全局配置異常模塊
'EXCEPTION_HANDLER': 'utils.response.exception.custom_handler',
# 修改默認返回JSON的renderer的類
'DEFAULT_RENDERER_CLASSES': ('utils.response.renderer.CustomRenderer',),
}
現在就完成了~ 就是這麼簡單。
(比AspNetCore包裝返回值簡單……)
完整代碼可以在GitHub上查看://github.com/Deali-Axy/DjangoStarter
參考資料
- Django rest framework自定義返回數據格式://blog.csdn.net/qq_41475058/article/details/112676908