Django Q2
Django Q2 is a native Django task queue, scheduler, and worker application using Python multiprocessing. It is a maintained fork of the original Django Q project, offering asynchronous tasks, scheduled jobs, and Django Admin integration. The current version is 1.9.0, and it has an active release cadence with multiple updates per year, regularly incorporating support for newer Django and Python versions.
Warnings
- breaking Python 3.8 support was dropped in `django-q2` v1.8.0. Ensure your Python environment is 3.9 or higher when upgrading.
- breaking Django 3.2 and 4.1 support was dropped in `django-q2` v1.7.0. Subsequent versions require Django 4.2 or newer, with v1.9.0 adding support for Django 6.0.
- gotcha If using Redis as your broker, `django-q2` v1.9.0 introduced a fix for compatibility with `redis-py > 5`. Ensure you are on `django-q2` v1.9.0 or higher if using recent `redis-py` versions to avoid potential issues.
- gotcha The `SECRET_KEY` in your Django settings is crucial as Django Q2 uses it to sign task packages. Without a properly set `SECRET_KEY`, tasks might fail to unpack or execute securely.
- gotcha A bug existed in versions prior to 1.7.0 where setting `max_attempts` to 1 would still result in the task being retried once. This could lead to unexpected duplicate executions.
- deprecated The original `django-q` project is no longer maintained. Users are strongly advised to migrate to `django-q2` for continued support and updates. Migration typically involves uninstalling `django-q` and installing `django-q2`.
Install
-
pip install django-q2 -
pip install django-q2[redis]
Imports
- async_task
from django_q.tasks import async_task
- schedule
from django_q.tasks import schedule
- Schedule
from django_q.models import Schedule
Quickstart
import os
import django
from django.conf import settings
# Minimal Django setup if running outside a full Django environment
if not settings.configured:
settings.configure(
INSTALLED_APPS=[
'django_q',
# Add other apps if needed
],
DATABASES={
'default': {
'ENGINE': 'django.db.backends.sqlite3',
'NAME': ':memory:',
}
},
Q_CLUSTER={
'name': 'myproject',
'workers': 4,
'timeout': 90,
'compress': True,
'save_limit': 250,
'queue_limit': 500,
'cpu_affinity': 1,
'label': 'Django Q2',
'redis': os.environ.get('REDIS_URL', 'redis://localhost:6379/0'),
},
SECRET_KEY=os.environ.get('DJANGO_SECRET_KEY', 'a-very-secret-key-for-development'),
TIME_ZONE='UTC',
USE_TZ=True,
)
django.setup()
# Your task function (e.g., in a tasks.py file)
def my_long_running_task(iterations):
result = 0
for i in range(iterations):
result += i
return result
# Enqueue the task
from django_q.tasks import async_task
task_id = async_task('my_app.tasks.my_long_running_task', 1000000)
print(f"Task enqueued with ID: {task_id}")
# To run the cluster in a separate terminal:
# python manage.py qcluster