[Fixed]-Difference between JSONParser and JSONRenderer


I will start with viewsets. View and viewsets are classes in DRF, where most of application logic happens.

Eg. ModelViewSet is class responsible for CRUD operations in response to POST, PUT, PATCH, GET, DELETE HTTP methods.

Lets take look at default create method from https://github.com/tomchristie/django-rest-framework/blob/master/rest_framework/mixins.py this method create instance of your model, from data (if they are valid) send via HTTP POST method and persist them to database.

def create(self, request, *args, **kwargs):
        serializer = self.get_serializer(data=request.data)
        headers = self.get_success_headers(serializer.data)
        return Response(serializer.data, status=status.HTTP_201_CREATED, headers=headers)

def perform_create(self, serializer):

This is whats happening here.

self.get_serializer() create new instance of serializer (you set serializer class before), it takes request.data as argument. request.data is (this is importent) dictionary. Dictionary is generic python data structure.

serializer.is_valid() method checks if request.data are valid. If yes you can access serializer.data – also a dictionary.

serializer.save() method creates and persist actual instance of your model (Snippet) to database.
You can directly access instance like this

instance = serializer.save()

Then you return Response object populated with serializer.data back to client.

As you can see, there is no Form data,JSON, XML, HTML etc. in viewset. You work with python data types and serializer is reponsible of “translating” dictionary to instance of your specific model and backwards.
But client send data (in your case) in HTTP request in form of JSON.

JSONParser is responsible of converting JSON to dictionary. Parsing is implemented inside request class https://github.com/tomchristie/django-rest-framework/blob/master/rest_framework/request.py , please notice that is not standard django HttpRequest model.

You can set multiple parsers, then request will choose proper one according to HTTP request header: Content-type.

Second thing is, you have to return serializer.data back to client in form of JSON, not dictionary. Thats what JSONRenderer does. It convert dict to JSON and its implemented inside Response class https://github.com/tomchristie/django-rest-framework/blob/master/rest_framework/response.py. Also you can set multiple renderers and then the proper one is choose according to accepted media type http header.

Example of full viewset definition might be:

from snippets.models import Snippet
from snippets.serializers import SnippetSerializer
from rest_framework.renderers import JSONRenderer
from rest_framework.parsers import JSONParser

class SnippetViewSet(viewsets.ModelViewSet):

    queryset = Snippet.objects.all()
    serializer_class = SnippetSerializer
    renderer_classes = (JSONRenderer, )
    parser_classes = (JSONParser,)

Leave a comment