Skip to content

Add ReactPy to a Django Project

Overview

If you want to add some interactivity to your existing Django project, you don't have to rewrite it in ReactPy. Use ReactPy-Django to add ReactPy to your existing stack, and render interactive components anywhere.

Note

These docs assumes you have already created a Django project, which involves creating and installing at least one Django app.

If do not have a Django project, check out this 9 minute YouTube tutorial created by IDG TECHtalk.


Step 1: Install from PyPI

Run the following command to install reactpy-django in your Python environment.

pip install reactpy-django

Step 2: Configure settings.py

Add "reactpy_django" to INSTALLED_APPS in your settings.py file.

1
2
3
4
INSTALLED_APPS = [
    ...,
    "reactpy_django",
]
Enable ASGI and Django Channels (Required)

ReactPy-Django requires Django ASGI and Django Channels WebSockets.

If you have not enabled ASGI on your Django project yet, here is a summary of the django and channels installation docs:

  1. Install channels[daphne]
  2. Add "daphne" to INSTALLED_APPS.

    INSTALLED_APPS = [
        "daphne",
        ...,
    ]
    
  3. Set your ASGI_APPLICATION variable.

    ASGI_APPLICATION = "example_project.asgi.application"
    
Configure ReactPy settings (Optional)

These are ReactPy-Django's default settings values. You can modify these values in your Django project's settings.py to change the behavior of ReactPy.

Setting Default Value Example Value(s) Description
REACTPY_CACHE "default" "my-reactpy-cache" Cache used to store ReactPy web modules. ReactPy benefits from a fast, well indexed cache. We recommend installing redis or python-diskcache.
REACTPY_DATABASE "default" "my-reactpy-database" Database used to store ReactPy session data. ReactPy requires a multiprocessing-safe and thread-safe database. If configuring REACTPY_DATABASE, it is mandatory to enable our database router like such:
DATABASE_ROUTERS = ["reactpy_django.database.Router", ...]
REACTPY_SESSION_MAX_AGE 259200 0, 60, 96000 Maximum seconds to store ReactPy session data, such as args and kwargs passed into your component template tag. Use 0 to not store any session data.
REACTPY_URL_PREFIX "reactpy/" "rp/", "render/reactpy/" The prefix to be used for all ReactPy WebSocket and HTTP URLs.
REACTPY_DEFAULT_QUERY_POSTPROCESSOR "reactpy_django.utils.django_query_postprocessor" None, "example_project.my_query_postprocessor" Dotted path to the default reactpy_django.hooks.use_query postprocessor function. Postprocessor functions can be async or sync, and the parameters must contain the arg data. Set REACTPY_DEFAULT_QUERY_POSTPROCESSOR to None to globally disable the default postprocessor.
REACTPY_AUTH_BACKEND "django.contrib.auth.backends.ModelBackend" "example_project.auth.MyModelBackend" Dotted path to the Django authentication backend to use for ReactPy components. This is only needed if:
1. You are using AuthMiddlewareStack and...
2. You are using Django's AUTHENTICATION_BACKENDS setting and...
3. Your Django user model does not define a backend attribute.
REACTPY_BACKHAUL_THREAD False True Whether to render ReactPy components in a dedicated thread. This allows the web server to process traffic during ReactPy rendering. Vastly improves throughput with web servers such as hypercorn and uvicorn.
REACTPY_DEFAULT_HOSTS None ["localhost:8000", "localhost:8001", "localhost:8002/subdir" ] The default host(s) that can render your ReactPy components. ReactPy will use these hosts in a round-robin fashion, allowing for easy distributed computing. You can use the host argument in your template tag as a manual override.
REACTPY_RECONNECT_INTERVAL 750 100, 2500, 6000 Milliseconds between client reconnection attempts. This value will gradually increase if REACTPY_RECONNECT_BACKOFF_MULTIPLIER is greater than 1.
REACTPY_RECONNECT_MAX_INTERVAL 60000 10000, 25000, 900000 Maximum milliseconds between client reconnection attempts. This allows setting an upper bound on how high REACTPY_RECONNECT_BACKOFF_MULTIPLIER can increase the time between reconnection attempts.
REACTPY_RECONNECT_MAX_RETRIES 150 0, 5, 300 Maximum number of reconnection attempts before the client gives up.
REACTPY_RECONNECT_BACKOFF_MULTIPLIER 1.25 1, 1.5, 3 Multiplier for the time between client reconnection attempts. On each reconnection attempt, the REACTPY_RECONNECT_INTERVAL will be multiplied by this to increase the time between attempts. You can keep time between each reconnection the same by setting this to 1.

Step 3: Configure urls.py

Add ReactPy HTTP paths to your urlpatterns in your urls.py file.

1
2
3
4
5
6
from django.urls import include, path

urlpatterns = [
    ...,
    path("reactpy/", include("reactpy_django.http.urls")),
]

Step 4: Configure asgi.py

Register ReactPy's WebSocket using REACTPY_WEBSOCKET_ROUTE in your asgi.py file.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
import os

from django.core.asgi import get_asgi_application

# Ensure DJANGO_SETTINGS_MODULE is set properly based on your project name!
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "example_project.settings")

# Fetch ASGI application before importing dependencies that require ORM models.
django_asgi_app = get_asgi_application()


from channels.routing import ProtocolTypeRouter, URLRouter  # noqa: E402
from reactpy_django import REACTPY_WEBSOCKET_ROUTE  # noqa: E402

application = ProtocolTypeRouter(
    {
        "http": django_asgi_app,
        "websocket": URLRouter([REACTPY_WEBSOCKET_ROUTE]),
    }
)
Add AuthMiddlewareStack and SessionMiddlewareStack (Optional)

There are many situations where you need to access the Django User or Session objects within ReactPy components. For example, if you want to:

  1. Access the User that is currently logged in
  2. Login or logout the current User
  3. Access Django's Session object

In these situations will need to ensure you are using AuthMiddlewareStack and/or SessionMiddlewareStack.

from channels.auth import AuthMiddlewareStack  # noqa: E402
from channels.sessions import SessionMiddlewareStack  # noqa: E402

application = ProtocolTypeRouter(
    {
        "http": django_asgi_app,
        "websocket": SessionMiddlewareStack(
            AuthMiddlewareStack(
                URLRouter(
                    [REACTPY_WEBSOCKET_ROUTE],
                )
            )
        ),
    }
)
Where is my asgi.py?

If you do not have an asgi.py, follow the channels installation guide.

Step 5: Run database migrations

Run Django's migrate command to initialize ReactPy-Django's database table.

python manage.py migrate

Step 6: Check your configuration

Run Django's check command to verify if ReactPy was set up correctly.

python manage.py check

Step 7: Create your first component

The next step will show you how to create your first ReactPy component.

Prefer a quick summary? Read the At a Glance section below.

At a Glance: Your First Component

my_app/components.py

You will need a file to define your ReactPy components. We recommend creating a components.py file within your chosen Django app to start out. Within this file, we will create a simple hello_world component.

1
2
3
4
5
from reactpy import component, html

@component
def hello_world(recipient: str):
    return html.h1(f"Hello {recipient}!")

my_app/templates/my-template.html

In your Django app's HTML template, you can now embed your ReactPy component using the component template tag. Within this tag, you will need to type in the dotted path to the component.

Additionally, you can pass in args and kwargs into your component function. After reading the code below, pay attention to how the function definition for hello_world (from the previous example) accepts a recipient argument.

1
2
3
4
5
6
7
{% load reactpy %}
<!DOCTYPE html>
<html>
  <body>
    {% component "example_project.my_app.components.hello_world" recipient="World" %}
  </body>
</html>

Last update: September 7, 2023
Authors: Mark Bakhit