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 aQueryDict. 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:
[
'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:
REST_FRAMEWORK = {
'DEFAULT_PARSER_CLASSES': [
'rest_framework.parsers.JSONParser',
]
}Or on a per-view basis:
Class-Based Views
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
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:
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.
