You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于Django REST Framework实现API统一BaseResponse响应格式问询

嘿,我来帮你搞定Django REST Framework统一响应格式的问题!结合你提到的BaseResponse思路,我先分析下可能踩的坑,再给你两种靠谱的实现方案:

先说说你之前代码可能存在的问题

大概率是你的BaseResponse.to_dict()只返回了普通字典,没有结合DRF的Response对象来处理,导致:

  • HTTP状态码没有正确映射到响应头
  • 异常场景(比如参数验证失败、服务器错误)的响应格式没法统一
  • 没法利用DRF自带的内容协商、渲染器等特性

方案一:完善BaseResponse,配合视图手动调用

这种方式适合需要在不同视图里灵活调整响应消息或状态码的场景,核心是让BaseResponse生成DRF标准的Response对象:

1. 重构BaseResponse类

from rest_framework.response import Response

class BaseResponse:
    def __init__(self, code=200, message="操作成功", data=None):
        self.code = code
        self.message = message
        self.data = data or {}

    def to_response(self):
        # 构造统一的响应结构
        response_payload = {
            "code": self.code,
            "message": self.message,
            "data": self.data
        }
        # 返回DRF的Response对象,自动处理状态码和响应头
        return Response(response_payload, status=self.code)

2. 在视图中使用

from rest_framework.views import APIView
from .models import YourModel
from .serializers import YourModelSerializer

class YourModelListView(APIView):
    def get(self, request):
        queryset = YourModel.objects.all()
        serializer = YourModelSerializer(queryset, many=True)
        # 直接返回封装后的响应
        return BaseResponse(data=serializer.data).to_response()

    # 举个异常场景的例子
    def post(self, request):
        serializer = YourModelSerializer(data=request.data)
        if not serializer.is_valid():
            # 自定义错误码和消息
            return BaseResponse(
                code=400,
                message="参数验证失败",
                data=serializer.errors
            ).to_response()
        serializer.save()
        return BaseResponse(data=serializer.data).to_response()

方案二:全局统一渲染器(更优雅,推荐)

如果想让所有API自动套用统一格式,不用每个视图都写BaseResponse,可以用DRF的自定义渲染器,全局生效:

1. 创建自定义渲染器

在你的app下新建renderers.py:

from rest_framework.renderers import JSONRenderer

class CustomJSONRenderer(JSONRenderer):
    def render(self, data, accepted_media_type=None, renderer_context=None):
        renderer_context = renderer_context or {}
        response = renderer_context.get('response')
        
        # 处理异常响应(比如4xx、5xx状态码)
        if response and response.status_code >= 400:
            # 把DRF默认的错误信息转成统一格式
            error_msg = data.get("detail", "请求出错")
            # 如果是序列化器验证错误,取第一个错误提示
            if isinstance(data, dict) and any(isinstance(v, list) for v in data.values()):
                first_error = next(iter(data.values()))[0]
                error_msg = first_error
            unified_data = {
                "code": response.status_code,
                "message": error_msg,
                "data": {}
            }
        else:
            # 正常响应统一包装
            unified_data = {
                "code": response.status_code if response else 200,
                "message": "操作成功",
                "data": data
            }
        
        # 调用父类方法渲染成JSON
        return super().render(unified_data, accepted_media_type, renderer_context)

2. 在settings.py中配置全局渲染器

REST_FRAMEWORK = {
    # 替换默认的JSON渲染器为自定义的
    'DEFAULT_RENDERER_CLASSES': [
        'your_app.renderers.CustomJSONRenderer',  # 替换成你的实际路径
        'rest_framework.renderers.BrowsableAPIRenderer',  # 保留DRF的可浏览API界面
    ],
}

3. 配合自定义异常处理(可选)

如果想更精准控制异常响应,还可以自定义异常处理函数,在utils.py中:

from rest_framework.views import exception_handler
from rest_framework.response import Response

def custom_exception_handler(exc, context):
    # 先调用DRF默认的异常处理逻辑
    response = exception_handler(exc, context)
    
    if response is not None:
        # 统一异常格式
        response.data = {
            "code": response.status_code,
            "message": response.data.get("detail", "服务器内部错误"),
            "data": {}
        }
    
    return response

然后在settings中配置:

REST_FRAMEWORK = {
    # ...其他配置
    'EXCEPTION_HANDLER': 'your_app.utils.custom_exception_handler',
}

两种方案对比

  • 方案一:灵活度高,适合需要在特定视图自定义响应消息的场景,但需要每个视图手动调用
  • 方案二:全局统一,代码更简洁,不用重复编写包装逻辑,推荐用于大部分项目

你可以根据自己的需求选一种,要是之前的BaseResponse有具体代码,也可以贴出来我帮你针对性修改!

内容的提问来源于stack exchange,提问作者Alec

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.20 10:06:27