前言
最近實在太忙了,開始了一個新的專案,為了快速形成產品,我選擇了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上檢視:https://github.com/Deali-Axy/DjangoStarter
參考資料
- Django rest framework自定義返回資料格式:https://blog.csdn.net/qq_41475058/article/details/112676908