How to return custom JSON in Django REST Framework
Solution 1
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'})
Solution 2
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
Roberto
Updated on July 05, 2022Comments
-
Roberto almost 2 years
I am trying to return custom json with
get_queryset
but always get404 error
in response.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')
If I delete everything starting from
def
I'll got correct response with standard json data. What I am doing wrong? -
bakkal over 5 years@VaggelisManousakis The same job in different scenarios: if all I am doing is returning custom data, I would go with the direct route of the
APIView
. If I'm using aModelViewSet
and need some custom data, I would override the methods that I need. -
Omar Jandali almost 5 yearswoudl you mind taking a look at this quest from me! stackoverflow.com/questions/56978902/…
-
Marc Gruita over 2 yearsyou should now use JsonResponse() instead of Response() to return custom json from an APIView