How to return custom JSON in Django REST Framework How to return custom JSON in Django REST Framework json json

How to return custom JSON in Django REST Framework


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'})


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