Skip to content

Parsers

Parsers handle the incoming HTTP request body and parse it into native Python data types (available as request.data), which are then passed to serializers.

Parsers vs Serializers

Parsers operate at the network level, translating raw HTTP payloads into basic Python data types (like dictionaries). Serializers operate at the application level, validating those basic types and converting them into complex Database models.

Built-in Parsers

DRF provides several built-in parsers:

  • JSONParser: Parses JSON request content. This is the standard parser for most JSON APIs.
  • FormParser: Parses standard HTML form content (application/x-www-form-urlencoded). Data is populated as a QueryDict. Useful for endpoints that need to accept data from standard web forms.
  • MultiPartParser: Parses multipart HTML form content (multipart/form-data). This is required if your API needs to accept file uploads from an HTML form.
  • FileUploadParser: Parses raw file upload content, returning a single uploaded file. Useful when a client uploads a file as the raw request body, rather than encoding it inside a multipart form.

Setting Parsers

By default, if you don't configure anything, DRF uses the following parsers:

python
[
    'rest_framework.parsers.JSONParser',
    'rest_framework.parsers.FormParser',
    'rest_framework.parsers.MultiPartParser'
]

This means your API can automatically handle JSON payloads from programmatic clients, as well as regular web form submissions (including file uploads) right out of the box.

You can override these globally in your settings.py:

python
REST_FRAMEWORK = {
    'DEFAULT_PARSER_CLASSES': [
        'rest_framework.parsers.JSONParser',
    ]
}

Or on a per-view basis:

Class-Based Views

python
from rest_framework.parsers import JSONParser
from rest_framework.response import Response
from rest_framework.views import APIView

class ExampleView(APIView):
    parser_classes = [JSONParser]

    def post(self, request, format=None):
        return Response({'received data': request.data})

Function-Based Views

python
from rest_framework.decorators import api_view, parser_classes
from rest_framework.parsers import JSONParser
from rest_framework.response import Response

@api_view(['POST'])
@parser_classes([JSONParser])
def example_view(request):
    return Response({'received data': request.data})

Custom Parsers

To implement a custom parser, subclass BaseParser, set the .media_type property and override the .parse() method.

The .parse() method receives the raw request stream and must return the parsed data (typically a dictionary or list) which will be used to populate request.data.

Text-based Parsers

For custom text formats (like plain text), simply read from the stream and decode it:

python
from rest_framework import parsers

class PlainTextParser(parsers.BaseParser):
    media_type = 'text/plain'

    def parse(self, stream, media_type=None, parser_context=None):
        """
        Reads the incoming bytestream and decodes it to a string.
        """
        return stream.read().decode('utf-8')

TIP

Don't want to build your own? There are many excellent Third-Party Packages available that provide ready-to-use parsers for formats like YAML, XML, MessagePack etc.