在使用 drf 的时候,当有错误的时候默认的 http response 都是 http state ,但是和前端的交互中,前端希望得到如下的这种 json 形式,包括我自己写前端的时候也想要这种形式的返回。
{
"code": 200,
"msg": "ok",
"data": { some data }
}
{
"code": 404,
"msg": "http not found",
"data": null
}
我说一下我之前的实现,这种实现我认为很怪,而且并不能完美封装一些 500 错误,想请教一下有没有什么可以优雅的方式。
首先我使用一个 dataclasses.dataclass 进行定义返回数据结构(code,msg,data)
from dataclasses import dataclass
from typing import Any
@dataclass
class Result:
code: int
msg: str
data: Any
后面我需要打各种补丁
- 在 api view 中使用 JsonResponse 进行返回,当然也包括一些业务上的逻辑判断都可以在这里进行处理
from dataclasses import asdict
from django.http import JsonResponse
from rest_framework import views
class SomeApiView(views.APIView):
def get(, request, *args, **kwargs) -> JsonResponse:
# do something
return JsonResponse(asdict(Result(200, 'ok', null)))
- modelviewset 的处理(继承 mixin 对返回做处理),如下,只写了一个举例:
from dataclasses import asdict
from django.http import JsonResponse
from rest_framework import status, mixins
class MyRetrieveModelMixin(mixins.RetrieveModelMixin):
def retrieve(self, request, *args, **kwargs):
instance = self.get_object()
serializer = self.get_serializer(instance)
return JsonResponse(asdict(Result(200, 'ok', serializer.data)))
- 全局异常处理,对类似 drf-jwt,drf-serializer 中的一些错误,只能在 settings.py 中的 rest framework 中进行异常处理配置,并且用这个方法去处理,这种形式总感觉特别怪。
# 配置
REST_FRAMEWORK = {
# ...
# 异常处理(统一封装为 code msg data 格式)
'EXCEPTION_HANDLER': 'utils.result_handler.custom_exception_handler',
# ...
}
def custom_exception_handler(exc, context):
response = exception_handler(exc, context)
if response is not None:
# logger
# 进行一些处理 处理成 Result(code, msg, data)
# 这里对很多处理,尤其 serializer 中的处理 特别烦!
# 比如手机号唯一约束,前端就想要 code:400 msg:"该手机号已被使用"
return JsonResponse(...)