Installation¶
Requirements¶
Before installing, ensure your environment meets these requirements:
Python ≥ 3.11
Django ≥ 4.2
Redis ≥ 6 (required in production for channel layer and cache)
Dependencies¶
The package installs the following libraries automatically:
Package |
Purpose |
|---|---|
|
Serializers used throughout the package (required even if you have no REST views) |
|
Object-level permissions for group admins and channel moderators |
|
Single-table polymorphic Room model |
|
Polymorphic serializers for room lists |
|
Recursive serialization for message replies and forwards |
|
XSS sanitisation on message content |
|
Django Channels ASGI WebSocket support |
|
Redis channel layer for production |
|
ASGI server (recommended) |
Install the Package¶
pip install django-realtime-chat-messaging
Configure INSTALLED_APPS¶
Add the following apps to your INSTALLED_APPS in settings.py. Order
matters — daphne must come before django.contrib.staticfiles.
INSTALLED_APPS = [
"daphne", # only add if using daphne as your ASGI server
"channels",
"django.contrib.admin",
"django.contrib.auth",
"polymorphic",
"django.contrib.contenttypes",
"django.contrib.sessions",
"django.contrib.messages",
"django.contrib.staticfiles",
"guardian",
"realtime_chat_messaging",
# ... your other apps
]
Note
Add "daphne" to INSTALLED_APPS only when you want python manage.py
runserver to use Daphne in development. In production you will start Daphne
directly from the command line and do not need it in INSTALLED_APPS.
Add Guardian Authentication Backend¶
django-guardian requires its object permission backend to be registered:
AUTHENTICATION_BACKENDS = (
"django.contrib.auth.backends.ModelBackend",
"guardian.backends.ObjectPermissionBackend",
)
Configure the ASGI Application¶
Set your ASGI application in settings.py:
ASGI_APPLICATION = "yourproject.asgi.application"
Then create or update asgi.py. The example below uses
django-channels-jwt-auth-middleware for JWT-based WebSocket authentication,
which is the recommended approach especially with REST APIs:
import os
import django
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "yourproject.settings")
# django.setup() must be called before importing anything that uses the app registry.
# This prevents AppRegistryNotReady errors when running with Daphne.
django.setup()
from django.core.asgi import get_asgi_application
from channels.routing import ProtocolTypeRouter, URLRouter
from channels.security.websocket import AllowedHostsOriginValidator
from realtime_chat_messaging.routing import websocket_urlpatterns
from django_channels_jwt_auth_middleware.auth import JWTAuthMiddlewareStack
django_asgi_app = get_asgi_application()
application = ProtocolTypeRouter(
{
"http": django_asgi_app,
"websocket": AllowedHostsOriginValidator(
JWTAuthMiddlewareStack(URLRouter(websocket_urlpatterns))
),
}
)
Important
AllowedHostsOriginValidator validates the WebSocket connection’s origin
header against Django’s ALLOWED_HOSTS setting. If the host is not listed,
the connection is rejected silently before it reaches your consumer.
Make sure ALLOWED_HOSTS is set in settings.py:
# Development — allow any host
ALLOWED_HOSTS = ["*"]
# Production — list your hostnames explicitly
# ALLOWED_HOSTS = ["example.com", "www.example.com"]
Forgetting this is one of the most common reasons WebSocket connections fail
after a fresh setup. Never use "*" in production.
Warning
AllowedHostsOriginValidator reads directly from Django’s ALLOWED_HOSTS
setting to decide whether to accept or reject each incoming WebSocket
connection. If ALLOWED_HOSTS is empty or does not include the host your
client is connecting from, every WebSocket connection will be rejected
with no meaningful error on the client side — the connection simply closes
immediately.
Make sure ALLOWED_HOSTS is set correctly before testing:
# settings.py — development
ALLOWED_HOSTS = ["localhost", "127.0.0.1"]
# settings.py — production
ALLOWED_HOSTS = ["example.com", "www.example.com"]
Never use ALLOWED_HOSTS = ["*"] in production.
Note
The package does not enforce any specific authentication method. The consumer
only requires that scope["user"] contains an authenticated Django user
object. How that user gets into the scope is entirely up to your middleware
stack. Common options include:
django-channels-jwt-auth-middleware(shown above, recommended for token-based APIs)Django Channels’ built-in
AuthMiddlewareStack(for session-based auth)Any custom middleware that populates
scope["user"]
Configure Channel Layers¶
Development (in-memory, single process only):
CHANNEL_LAYERS = {
"default": {
"BACKEND": "channels.layers.InMemoryChannelLayer",
}
}
Production (Redis, required for multi-process deployments):
CHANNEL_LAYERS = {
"default": {
"BACKEND": "channels_redis.core.RedisChannelLayer",
"CONFIG": {"hosts": [("localhost", 6379)]},
}
}
Configure Cache¶
The package uses Django’s cache framework to store user group memberships across reconnections. These cached memberships allow users to be automatically re-subscribed to their rooms on reconnect without a database query.
Development (local memory):
CACHES = {
"default": {
"BACKEND": "django.core.cache.backends.locmem.LocMemCache",
"LOCATION": "unique-dev-cache",
}
}
Production (Redis, same instance as channel layer is fine):
CACHES = {
"default": {
"BACKEND": "django.core.cache.backends.redis.RedisCache",
"LOCATION": "redis://localhost:6379",
}
}
Run Migrations¶
The package ships with its own migrations. Run them after completing the configuration above:
python manage.py migrate
Warning
If you plan to use custom (swappable) models, do not run migrations yet. Set up your custom models first, then migrate. See Custom Models for the full workflow including the important circular dependency fix.
Verify the Installation¶
Start your development server:
python manage.py runserver
Open a WebSocket client (e.g., the browser console or a tool like wscat) and
attempt to connect:
const ws = new WebSocket("ws://localhost:8000/messaging/");
ws.onopen = () => console.log("Connected");
ws.onmessage = (e) => console.log(JSON.parse(e.data));
An unauthenticated connection will be closed immediately with code 4001. Once
you have authentication middleware in place and send a valid token, the connection
will be accepted and any pending notifications will be dispatched automatically.