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.