DRF: Faster Serialization with orjson

The speed at which APIs serialize and deserialize data is a crucial factor for the performance of a web application.

Bernd Fischer

Bernd Fischer

10. Nov 2024 · 4 min read

DRF: Faster Serialization with orjson

Orjson

In Django REST Framework (DRF), serialization handles converting data from Python objects to JSON and vice versa. The Python standard library provides the json package for this purpose, but it hits its limits with large or frequent data queries. A more performant alternative is using orjson, a JSON library for Python written in RUST, which offers significant speed advantages especially with large data volumes.

Prerequisites

Before starting this tutorial, make sure you have Django and Django REST Framework installed. If not, install them with:

pip install django djangorestframework

Then install the orjson renderer library:

pip install drf-orjson-renderer

Creating the Project and App

If you don't have a Django project yet, you can create one with the following commands:

django-admin startproject myproject
cd myproject
python manage.py startapp myapp

Don't forget to add your app myapp to the INSTALLED_APPS in your project's settings.py.

Creating the Model

In this example, we create a simple model named Article, which will be serialized as JSON in our API:

# myapp/models.py
from django.db import models

class Article(models.Model):
    title = models.CharField(max_length=100)
    content = models.TextField()

    def __str__(self):
        return self.title

Now run the migrations to create the model in the database:

python manage.py makemigrations
python manage.py migrate

Creating a Serializer

For Django REST Framework, we need a serializer that converts the Article model data to JSON. Add the following code in serializers.py:

# myapp/serializers.py
from rest_framework import serializers
from .models import Article

class ArticleSerializer(serializers.ModelSerializer):
    class Meta:
        model = Article
        fields = ['id', 'title', 'content']

Setting Up Views and URLs

Create a ModelViewSet that uses the Article serializer to enable CRUD operations (Create, Read, Update, and Delete):

# myapp/views.py
from rest_framework.viewsets import ModelViewSet
from .models import Article
from .serializers import ArticleSerializer

class ArticleViewSet(ModelViewSet):
    queryset = Article.objects.all()
    serializer_class = ArticleSerializer

Now register this viewset in the URLs so it can be accessed via api/articles/.

# myapp/urls.py
from django.urls import path, include
from rest_framework.routers import DefaultRouter
from .views import ArticleViewSet

router = DefaultRouter()
router.register(r'articles', ArticleViewSet)

urlpatterns = [
    path('api/', include(router.urls)),
]

Don't forget to import this URL configuration in the main urls.py of your project.

Configuring drf-orjson-renderer

Now we come to the core optimization: setting up the drf-orjson-renderer. With this configuration, we use orjson for fast JSON rendering.

Open settings.py and adjust the DRF settings to use the ORJSONRenderer as the default renderer:

# settings.py
REST_FRAMEWORK = {
    "DEFAULT_RENDERER_CLASSES": (
        "drf_orjson_renderer.renderers.ORJSONRenderer",
        "rest_framework.renderers.BrowsableAPIRenderer",
    ),
}

This sets DRF to use orjson for all JSON serialization, improving performance compared to default renderers. Rendering refers to the process of serializing outgoing data as JSON.

The options of orjson enable serialization of special data types like dataclasses, numpy arrays, and non-string keys (e.g. numbers) to JSON, increasing compatibility and flexibility when handling complex data structures. This allows scientific or numerical data to be efficiently stored in JSON without additional conversion steps.

REST_FRAMEWORK = {
    "ORJSON_RENDERER_OPTIONS": (
        orjson.OPT_NON_STR_KEYS,
        orjson.OPT_SERIALIZE_DATACLASS,
        orjson.OPT_SERIALIZE_NUMPY,
    ),
}

To parse incoming data using orjson, we also set the parser:

REST_FRAMEWORK = {
    "DEFAULT_PARSER_CLASSES": (
        "drf_orjson_renderer.parsers.ORJSONParser",
    ),
}

Registering the Model in the Admin Dashboard

To manage the Article model in the Django admin dashboard, register it in admin.py:

# myapp/admin.py
from django.contrib import admin
from .models import Article

@admin.register(Article)
class ArticleAdmin(admin.ModelAdmin):
    list_display = ('title', 'content')
    search_fields = ('title',)

This enables you to add, modify, and delete articles in the admin area.

Testing the API

Start the server and access the API to test performance:

python manage.py runserver

Visit http://127.0.0.1:8000/api/articles/ – here you should see a list of Article data as a JSON response. Using orjson makes JSON output faster, which can lead to noticeable improvements with large or frequent data requests.