Skip to content

Renderers ​

Renderers determine how your API responses are formatted (e.g., JSON, HTML, XML). Before a Response object is returned to the client, it must be rendered into a byte stream.

Built-in Renderers ​

DRF provides several built-in renderers:

  • JSONRenderer: Renders the response data into JSON, using utf-8 encoding. This is the standard renderer for most JSON APIs.
  • TemplateHTMLRenderer: Renders data to HTML, using Django's standard template rendering. Useful when your API needs to serve standard HTML pages instead of pure data.
  • StaticHTMLRenderer: Returns pre-rendered HTML without any further processing. Useful for endpoints that return pre-compiled HTML fragments.
  • BrowsableAPIRenderer: Renders data into HTML for the browsable API. This is what powers DRF's famous self-documenting, interactive web API UI.
  • AdminRenderer: Renders data into HTML for an admin-like interface. Suitable for CRUD-style web APIs that should also present a user-friendly interface for managing the data.
  • MultiPartRenderer: Renders data as HTML multipart form data. This is primarily used for testing purposes, allowing you to easily simulate complex form submissions in your test suite.

Setting Renderers ​

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

python
[
    'rest_framework.renderers.JSONRenderer',
    'rest_framework.renderers.BrowsableAPIRenderer',
]

This means your API will automatically return JSON to programmatic clients, but will render the interactive Browsable API when accessed via a web browser.

You can override these globally in your settings.py:

python
REST_FRAMEWORK = {
    'DEFAULT_RENDERER_CLASSES': [
        'rest_framework.renderers.JSONRenderer',
    ]
}

Or on a per-view basis:

Class-Based Views ​

python
from rest_framework.renderers import JSONRenderer
from rest_framework.response import Response
from rest_framework.views import APIView

class UserCountView(APIView):
    renderer_classes = [JSONRenderer]

    def get(self, request, format=None):
        user_count = User.objects.count()
        return Response({'users': user_count})

Function-Based Views ​

python
from rest_framework.decorators import api_view, renderer_classes
from rest_framework.renderers import JSONRenderer
from rest_framework.response import Response

@api_view(['GET'])
@renderer_classes([JSONRenderer])
def user_count_view(request):
    user_count = User.objects.count()
    return Response({'users': user_count})

Custom Renderers ​

To implement a custom renderer, subclass BaseRenderer, set the .media_type and .format properties and override the .render() method.

The .render() method receives the response data and must return a bytestring to be used as the HTTP response body.

Text-based Renderers ​

For custom text formats (like CSV or plain text), simply format your data into a string and encode it using the specified charset (which defaults to utf-8):

python
from rest_framework.renderers import BaseRenderer

class PlainTextRenderer(BaseRenderer):
    media_type = 'text/plain'
    format = 'txt'
    charset = 'iso-8859-1'

    def render(self, data, accepted_media_type=None, renderer_context=None):
        # Format your data into a string, then encode it
        text_content = str(data)
        return text_content.encode(self.charset)

Binary Renderers ​

If your renderer returns raw binary data (like an image or PDF file), set the charset to None. You should also set render_style = 'binary' so the browsable API knows not to attempt displaying the binary output as text:

python
from rest_framework.renderers import BaseRenderer

class JPEGRenderer(BaseRenderer):
    media_type = 'image/jpeg'
    format = 'jpg'
    charset = None
    render_style = 'binary'

    def render(self, data, accepted_media_type=None, renderer_context=None):
        # `data` should already be raw bytes representing the image
        return data

TIP

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