django如何自定义 `Response` 对象来包裹返回的数据 最后更新时间:2025年07月02日 ### 方法一:重写 `list` 和 `retrieve` 方法 在视图类中直接修改返回格式: ```python 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 响应: ```python # 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` 中配置: ```python REST_FRAMEWORK = { 'DEFAULT_RENDERER_CLASSES': [ 'utils.renderers.CustomJSONRenderer', # 其他渲染器... ], } ``` ### 方法三:使用 Mixin 类 创建一个可复用的 Mixin 类,应用于需要此格式的视图: ```python 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) ``` 在视图中使用: ```python class TimeMoudelSet(CustomResponseMixin, viewsets.ModelViewSet): serializer_class = TimeMoudelSerializer # 其他代码保持不变... ``` ### 推荐方案(方法一) 针对你的视图,推荐直接重写 `list` 和 `retrieve` 方法,因为你可能只需要特定视图返回此格式: ```python 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. **兼容性**:如果前端已依赖原始格式,需谨慎修改。
Comments | NOTHING