【问题标题】:How to return custom JSON in Django REST Framework如何在 Django REST 框架中返回自定义 JSON
【发布时间】:2016-05-03 07:44:21
【问题描述】:

我正在尝试使用 get_queryset 返回自定义 json,但总是得到 404 error 作为响应。

class TestViewSet(viewsets.ModelViewSet):
    """
    API endpoint that allows groups to be viewed or edited.
    """
    queryset = Test.objects.all()
    serializer_class = TestSerializer

    def get_queryset(self):
        if self.request.method == "GET":
            content = {'user_count': '2'}
            return HttpResponse(json.dumps(content), content_type='application/json')

如果我删除从 def 开始的所有内容,我将得到标准 json 数据的正确响应。我做错了什么?

【问题讨论】:

  • 我从来没有使用过 DRF,但是通过查看函数名,get_queryset 不应该返回一个查询集吗?
  • @ShangWang 在这种情况下,使用什么方法更好地处理获取请求并使用自定义 json 进行响应?

标签: python json django django-rest-framework


【解决方案1】:

基于类的视图中,有两种方法可以使用 ModelViewSet

自定义响应

解决方案 1:views.py

中自定义
class StoryViewSet(viewsets.ModelViewSet):
    permission_classes = (permissions.AllowAny,)
    queryset = Story.objects.all()
    serializer_class = StorySerializer

    def retrieve(self, request, *args, **kwargs):
        # ret = super(StoryViewSet, self).retrieve(request)
        return Response({'key': 'single value'})

    def list(self, request, *args, **kwargs):
        # ret = super(StoryViewSet, self).list(request)
        return Response({'key': 'list value'})

解决方案 2:serializers.py 中自定义 (我推荐这个解决方案)

class StorySerializer(serializers.ModelSerializer):
    class Meta:
        model = Story
        fields = "__all__"

    def to_representation(self, instance):
        ret = super(StorySerializer, self).to_representation(instance)
        # check the request is list view or detail view
        is_list_view = isinstance(self.instance, list)
        extra_ret = {'key': 'list value'} if is_list_view else {'key': 'single value'}
        ret.update(extra_ret)
        return ret

【讨论】:

【解决方案2】:

如果您不需要 ModelViewSet 并且只想在 GET 请求上自定义 JSON

您也可以使用APIView,它不需要模型

class MyOwnView(APIView):
    def get(self, request):
        return Response({'some': 'data'})

urlpatterns = [
    url(r'^my-own-view/$', MyOwnView.as_view()),
]

使用模型视图集

您已将自定义 JSON 放入 get_queryset,这是错误的。如果你想使用ModelViewSet,这本身就足够了:

class TestViewSet(viewsets.ModelViewSet):
    queryset = Test.objects.all()
    serializer_class = TestSerializer

这个ModelViewSet 带有.list().retrieve().create().update().destroy() 的默认实现。您可以根据需要覆盖(自定义)哪些

.retrieve() 和/或 ModelViewSet 中的 .list() 返回自定义 JSON

例如覆盖.retrieve() 以在检索单个对象时返回自定义视图。我们可以看看default implementation which looks like this

def retrieve(self, request, *args, **kwargs):
    instance = self.get_object()
    serializer = self.get_serializer(instance)
    return Response(serializer.data)

以返回自定义 JSON 为例:

class TestViewSet(viewsets.ModelViewSet):
    queryset = Test.objects.all()
    serializer_class = TestSerializer

    def retrieve(self, request, *args, **kwargs):
        return Response({'something': 'my custom JSON'})

    def list(self, request, *args, **kwargs):
        return Response({'something': 'my custom JSON'})

【讨论】:

  • @VaggelisManousakis 在不同的场景中做同样的工作:如果我所做的只是返回自定义数据,我会选择APIView 的直接路由。如果我使用ModelViewSet 并需要一些自定义数据,我会覆盖我需要的方法。
  • 您现在应该使用 JsonResponse() 而不是 Response() 从 APIView 返回自定义 json
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-08-21
  • 1970-01-01
  • 2021-01-30
  • 1970-01-01
  • 2020-03-01
  • 2016-05-03
  • 1970-01-01
相关资源
最近更新 更多