How to return custom JSON in Django REST Framework

后端 未结 2 535
青春惊慌失措
青春惊慌失措 2020-12-07 17:54

I am trying to return custom json with get_queryset but always get 404 error in response.

class TestViewSet(viewsets.ModelViewSet):         


        
相关标签:
2条回答
  • 2020-12-07 17:58

    If you don't need a ModelViewSet and just want custom JSON on a GET request

    You can also use an APIView, which doesn't require a model

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

    and

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

    With a ModelViewSet

    You've put the custom JSON into get_queryset, that's wrong. If you want to use a ModelViewSet, this by itself should be enough:

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

    This ModelViewSet comes with default implementations for .list(), .retrieve(), .create(), .update(), and .destroy(). Which are available for you to override (customize) as needed

    Returning custom JSON from .retrieve() and/or .list() in ModelViewSet

    E.g. to override .retrieve() to return custom view when retrieving a single object. We can have a look at the 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)
    

    So as an example to return custom 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'})
    
    0 讨论(0)
  • 2020-12-07 18:06

    There are 2 ways to custom the response in Class-based views with ModelViewSet

    Solution 1: custom in 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'})
    

    Solution 2: custom in serializers.py (I recommend this solution)

    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
    
    0 讨论(0)
提交回复
热议问题