如何自定义 Django REST Framework GET 请求的响应?

Posted

技术标签:

【中文标题】如何自定义 Django REST Framework GET 请求的响应?【英文标题】:How to customize the response of Django REST Framework GET request? 【发布时间】:2016-12-29 05:36:59 【问题描述】:

我有一个模型 Foo,我用它作为我的 vanilla DRF 序列化程序的模型。

models.py

class Foo(models.Model):
    name = models.CharField(max_length=20)
    description = models.TextField()
    is_public = models.BooleanField(default=False)

serializers.py

class FooSerializer(serializers.ModelSerializer):
    class Meta:
        model = Foo

views.py

class FooRetrieveAPIView(RetrieveAPIView):
    queryset = Foo.objects.all()
    serializer_class = FooSerializer

现在前端代码正在使用这个端点的结果,这是识别下一页要显示的基础。无论如何,我需要更改状态200(现有记录)和404(不存在记录)返回的结果结构。

实际结果(来自原版 DRF):

$ curl localhost:8000/foo/1/  # existing record
"id": 1, "name": "foo", "description": "foo description", is_public=false

$ curl localhost:8000/foo/2/  # non-existent record
"detail": "Not found."

我希望结果如何:

$ curl localhost:8000/foo/1/
"error": "", "foo": "id": 1, "name": "foo", "description": "foo description", is_public=false

$ curl localhost:8000/foo/2/
"error": "Some custom error message", "foo": null

我主要使用 vanilla DRF,所以事情非常简单,所以这种响应结构的自定义对我来说有点新。

使用的 Django 版本:1.9.9

使用的 DRF 版本:3.3.x

【问题讨论】:

***.com/questions/35019030/…的可能重复 【参考方案1】:

您可以在视图中重写retrieve 方法以更新您的序列化器响应数据

class FooRetrieveAPIView(RetrieveAPIView):
    queryset = Foo.objects.all()
    serializer_class = FooSerializer

    def retrieve(self, request, *args, **kwargs):
        instance = self.get_object()
        serializer = self.get_serializer(instance)
        data = serializer.data
        # here you can manipulate your data response
        return Response(data)

【讨论】:

谢谢。这适用于200 响应。我需要做一些异常处理来获得正确的404 响应。【参考方案2】:

我遇到了类似的问题,不想创建自定义异常处理程序,因为我想更好地控制为 api 调用定义错误消息。 经过一番手敲,我在视图集中使用以下代码来获取自定义错误消息,同时使用 partial_update 更新记录。

 def partial_update(self, request, *args, **kwargs):
    partial = kwargs.pop('partial', False)
    try:
        instance = self.get_object()
        serializer = self.get_serializer(instance, data=request.data, partial=partial)
        serializer.is_valid(raise_exception=True)
        self.perform_update(serializer)
        headers = self.get_success_headers(serializer.data)
        response = "status": "True", "message": "", "data": serializer.data
        return Response(response, status=status.HTTP_201_CREATED, headers=headers)
    except exception.Http404:
        headers = ""
        response = "status": "False", "message": "Details not found", "data": ""
        return Response(response, status=status.HTTP_200_OK, headers=headers)

【讨论】:

以上是关于如何自定义 Django REST Framework GET 请求的响应?的主要内容,如果未能解决你的问题,请参考以下文章

如何在 django rest 框架中添加自定义权限和角色

如何在 Django REST 框架中为多对多字段定义“IsOwner”自定义权限?

如何自定义 Django Rest Framework 序列化程序输出?

如何在 django rest 框架中反转 ViewSet 自定义操作的 URL

Django Rest Framework 自定义身份验证

如何自定义 Django REST Framework GET 请求的响应?