Documentation: https://django-rmq.rdd-lab.com/
Source Code: https://github.com/RDDLab/Django-RMQ
Django-RMQ provides RabbitMQ wrappers and tools for Django projects, built on top of Pika. It is a lightweight integration layer — not a task queue or a Celery replacement — for projects that need to publish and consume messages while keeping broker infrastructure code predictable and close to the Django configuration. Supports RabbitMQ 3.13–4.3.
- Django-native settings — configure broker connections via
RABBITMQ_CONNECTIONSinsettings.py, one entry per alias. ProducerandConsumerwrappers — thin classes over Pika's blocking connection that handle channel lifecycle and lazy queue declaration.- Decorator-style publishing — use a
Producerinstance as a@producerdecorator to auto-publish a function's return value. - Reliable delivery — publisher confirms,
mandatory=True, anddelivery_mode=2(persistent) are enforced on every message. - Auto-reconnect with backoff — producers retry once on transient channel errors; consumers reconnect with exponential backoff capped at a configurable maximum.
- Dead-letter routing — declare queues with
QueueConfig(dead_letter_exchange=...)so unhandled messages are nacked without requeue and routed to a DLX. - Management commands —
setup_rabbitmq_topology(idempotent exchange/queue/binding setup) andstart_consumers(threaded runner with graceful SIGTERM/SIGINT shutdown). - Multiple connections — configure several broker aliases and select per producer/consumer via
using=. - Fully typed — ships
py.typed; compatible with pyrefly and standard type checkers.
pip install django-rmqAdd 'django_rmq' to INSTALLED_APPS and configure at least one connection alias:
INSTALLED_APPS = [
# ...
'django_rmq',
]
RABBITMQ_CONNECTIONS = {
'default': {
'HOST': 'localhost',
'PORT': 5672,
'VIRTUAL_HOST': '/',
'USER': 'guest',
'PASSWORD': 'guest',
'HEARTBEAT': 600,
'BLOCKED_CONNECTION_TIMEOUT': 300,
'RECONNECT_INITIAL_BACKOFF': 1.0,
'RECONNECT_MAX_BACKOFF': 30.0,
},
}Publish a message:
from django_rmq.producer import Producer
Producer(queue='orders').publish(body='{"order_id": 42}')Consume messages (e.g. myapp/consumers.py):
from pika.adapters.blocking_connection import BlockingChannel
from pika.spec import Basic, BasicProperties
from django_rmq.consumer import Consumer
from django_rmq.registries.registry import get_consumers_registry
consumer: Consumer = Consumer(queue='orders')
@consumer
def handle_order(
ch: BlockingChannel,
method: Basic.Deliver,
props: BasicProperties,
body: bytes,
) -> None:
print(body)
ch.basic_ack(delivery_tag=method.delivery_tag)
get_consumers_registry().register(consumer=consumer)Import consumers.py inside your app's AppConfig.ready(), then start consuming:
uv run python manage.py start_consumersFull reference, configuration guide, reliability details, and more:
https://django-rmq.rdd-lab.com/
Unit tests mock pika and need no broker. They run by default — integration
tests are marked integration and deselected:
uv run pytestIntegration tests run against a real RabbitMQ broker. The repo ships a
.github/docker-compose.yml that starts the same image CI uses (with the
management plugin the suite needs on port 15672). Connection params are read
from RMQ_* env vars (defaults: localhost:5672, guest/guest, vhost /),
which already match the Compose service:
docker compose -f .github/docker-compose.yml up -d --wait # start the broker, block until healthy
uv run pytest -m integration
docker compose -f .github/docker-compose.yml down # stop it when doneThe suite isolates itself with per-test uuid-suffixed queues/exchanges and
cleans them up, so it is safe against a shared broker (use a dedicated vhost).
MIT
