Install any skill in seconds. Free to start, no credit card required.
Get Started Free →Use when adding, changing, testing, or debugging Django Q2 background tasks, scheduled jobs, qcluster workers, Redis broker configuration, or ORM broker fallback in Django projects.
.claude/skills/hashgraph-online-django-q2/SKILL.md| Test case | Without → With | Effect | Δ tokens | Δ turns |
|---|---|---|---|---|
| case-05 | ✗→✓ | ▲ Improved | 40% | 0% |
| case-01 | ✓→✓ | = Same ✓ | 257% | 0% |
| case-02 | ✓→✓ | = Same ✓ | 69% | 0% |
| case-03 | ✓→✓ | = Same ✓ | 53% | 0% |
| case-04 | ✓→✓ | = Same ✓ | 113% | 0% |
Use this before touching task enqueueing, schedules, worker deployment, Q_CLUSTER, or code imported by Django Q2 workers.
django-q2; the Python import path is django_q.django_q is in INSTALLED_APPS; its migrations provide task result,schedule, and broker models.
Q_CLUSTER in the project's settings module before changing task,worker, or broker behavior.
variable such as REDIS_URL; the ORM broker is useful for low-throughput or Redis-free deployments.
python manage.py qcluster, but projects may wrap it with uv, Poetry, Docker Compose, process managers, or platform-specific worker declarations.
check, Docker, deployment, and documentation references separately.
async_task(...) or creates Schedule rows.qcluster process reserveswork.
failures.
nothing unless qcluster is running.
tasks.py module or another importable module already used by the project.
objects, local closures, or process-local state.
files, connections, or large payloads.
guarantees, and receipt-based brokers can re-run work.
transaction.on_commit(...).
pythondef send_welcome_email(user_id: int) -> None: from django.contrib.auth import get_user_model user = get_user_model().objects.get(pk=user_id) ...
pythonfrom django.db import transaction from django_q.tasks import async_task transaction.on_commit( lambda: async_task("myapp.tasks.send_welcome_email", user.pk) )
Use q_options when Django Q2 options would collide with task kwargs:
pythonasync_task( "myapp.tasks.rebuild_report", report_id, q_options={"timeout": 300, "group": "reports"}, )
Prefer named, idempotent schedules created by a migration, admin action, or setup command. Avoid creating schedules unconditionally at import time or app startup.
pythonfrom django_q.models import Schedule Schedule.objects.get_or_create( name="clear-expired-sessions", defaults={ "func": "django.core.management.call_command", "args": "'clearsessions'", "schedule_type": Schedule.HOURLY, }, )
Use Schedule.objects.get_or_create(name=..., defaults={...}) when seeding schedules so repeated setup does not duplicate jobs. Cron schedules require the optional croniter dependency; do not use Schedule.CRON unless the project includes it.
Missed schedules catch up by default. Set Q_CLUSTER["catch_up"] = False when a job should run once after downtime instead of replaying every missed interval.
Use Redis when the project already depends on it for workers or deployment:
pythonQ_CLUSTER = { "name": "...", "timeout": 3600, "workers": 4, "redis": REDIS_URL, }
Redis is fast and usually fits projects that already run Redis for cache, Docker, or deployment workers. The default Redis broker does not support delivery receipts. If a worker host dies catastrophically while executing a task, the in-flight package can be lost; if task code raises, Django Q2 records a failure. Use idempotent task design, explicit retries in task code where needed, and monitoring for failures.
Use the Django database broker only for low-throughput deployments, local simplicity, or environments where Redis is unavailable:
pythonQ_CLUSTER = { "name": "...", "timeout": 3600, "retry": 4800, "workers": 4, "max_attempts": 2, "orm": "default", }
When switching to ORM:
"redis" broker key; configure one broker per cluster unless youintentionally use custom clusters.
django_q. If the broker uses a non-default databasealias, run migrations with --database <alias>.
"poll" above the default 0.2 seconds, for example "poll": 2.0,when you need lower database polling pressure and can tolerate higher queue pickup latency.
separately. Schedules are always database rows; the broker setting controls queued task packages, not the schedule table.
async_task("myapp.tasks.fn", arg, sync=True)Q_CLUSTER["sync"] = Truethe project's qcluster command in a separate process and wait for result(task_id, 200) or a similar bounded wait; do not rely on arbitrary sleeps.
pytest.mark.django_db(transaction=True) when a real worker process mustobserve committed database rows.
qcluster process running with the same settings module, SECRET_KEY,broker URL, and cluster name as the web process?
django_q migrations?polling the expected database?
Schedule rowwith no stable name?
reporter?
Other measured skills in the registry, with their headline benchmark lift.