django如何自定义 `Response` 对象来包裹返回的数据


方法一:重写 listretrieve 方法

在视图类中直接修改返回格式:

from rest_framework.response import Response
class TimeMoudelSet(viewsets.ModelViewSet):
    serializer_class = TimeMoudelSerializer
    def get_queryset(self):
        now_time = datetime.datetime.now().timestamp()
        TimeMoudel.objects.filter(end_time__lt=now_time).update(status=False)
        return TimeMoudel.objects.filter(user_id=self.request.user.id, status=True)
    def list(self, request, *args, **kwargs):
        queryset = self.get_queryset()
        serializer = self.get_serializer(queryset, many=True)
        return Response({
            "data": serializer.data,
            "code": 200  # 自定义状态码
        })
    def retrieve(self, request, *args, **kwargs):
        instance = self.get_object()
        serializer = self.get_serializer(instance)
        return Response({
            "data": serializer.data,
            "code": 200
        })

方法二:自定义响应渲染器

通过全局配置统一处理所有 API 响应:

# utils/renderers.py
from rest_framework.renderers import JSONRenderer

class CustomJSONRenderer(JSONRenderer):
    def render(self, data, accepted_media_type=None, renderer_context=None):
        response = renderer_context['response']
        code = response.status_code
        # 错误处理(根据实际需求调整)
        if isinstance(data, dict) and 'detail' in data:
            return super().render({
                "data": None,
                "code": code,
                "message": data['detail']
            }, accepted_media_type, renderer_context)
        # 成功响应
        return super().render({
            "data": data,
            "code": code
        }, accepted_media_type, renderer_context)

settings.py 中配置:

REST_FRAMEWORK = {
    'DEFAULT_RENDERER_CLASSES': [
        'utils.renderers.CustomJSONRenderer',
        # 其他渲染器...
    ],
}

方法三:使用 Mixin 类

创建一个可复用的 Mixin 类,应用于需要此格式的视图:

from rest_framework.response import Response

class CustomResponseMixin:
    def finalize_response(self, request, response, *args, **kwargs):
        if isinstance(response.data, list) or isinstance(response.data, dict):
            response.data = {
                "data": response.data,
                "code": response.status_code
            }
        return super().finalize_response(request, response, *args, **kwargs)

在视图中使用:

class TimeMoudelSet(CustomResponseMixin, viewsets.ModelViewSet):
    serializer_class = TimeMoudelSerializer
    # 其他代码保持不变...

推荐方案(方法一)

针对你的视图,推荐直接重写 listretrieve 方法,因为你可能只需要特定视图返回此格式:

class TimeMoudelSet(viewsets.ModelViewSet):
    serializer_class = TimeMoudelSerializer
    def get_queryset(self):
        now_time = datetime.datetime.now().timestamp()
        TimeMoudel.objects.filter(end_time__lt=now_time).update(status=False)
        return TimeMoudel.objects.filter(user_id=self.request.user.id, status=True)
    def list(self, request, *args, **kwargs):
        queryset = self.get_queryset()
        serializer = self.get_serializer(queryset, many=True)
        return Response({
            "data": serializer.data,
            "code": 200,
            "message": "获取成功"  # 可选消息
        })
    def retrieve(self, request, *args, **kwargs):
        instance = self.get_object()
        serializer = self.get_serializer(instance)
        return Response({
            "data": serializer.data,
            "code": 200,
            "message": "获取成功"
        })

注意事项

  1. 错误处理:确保在错误情况下(如 404、400 等)也返回统一格式。
  2. 状态码code 字段与 HTTP 状态码不同,可根据业务需求自定义(如 code=1000 表示业务成功)。
  3. 兼容性:如果前端已依赖原始格式,需谨慎修改。

声明:一代明君的小屋|版权所有,违者必究|如未注明,均为原创|本网站采用BY-NC-SA协议进行授权

转载:转载请注明原文链接 - django如何自定义 `Response` 对象来包裹返回的数据


欢迎来到我的小屋