【问题标题】:How to customize the response of Django REST Framework GET request?如何自定义 Django REST Framework GET 请求的响应?
【发布时间】: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

【问题讨论】:

标签: django django-rest-framework


【解决方案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)

【讨论】:

    猜你喜欢
    • 2020-11-09
    • 1970-01-01
    • 2019-06-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-02-18
    • 1970-01-01
    • 2020-08-26
    相关资源
    最近更新 更多