Communitygithub.com

django-celery

Django + Celery asynchrone Aufgabenmuster – Konfiguration, Aufgabenentwurf, Beat-Zeitplanung, Wiederholungen, Canvas-Workflows, Überwachung und Tests. Verwenden Sie dies, um Hintergrundjobs, geplante Aufgaben oder asynchrone Verarbeitung zu einer Django-App hinzuzufügen.

Was ist django-celery?

Diese Anleitung beschreibt produktionsreife Muster für die Ausführung von Hintergrundaufgaben in Django mit Celery und Redis oder RabbitMQ als Nachrichtenbroker. Sie deckt die gesamte Einrichtung ab, von der Installation und Konfiguration von Celery in einer Django-Projektstruktur über die Definition von Aufgaben (einfach, wiederholbar, idempotent, mit Soft-Time-Limit) bis hin zu fortgeschrittenen Workflows mittels Celery Canvas (Chains, Groups, Chords). Zudem wird die periodische Aufgabenplanung über Celery Beat sowohl im Code als auch über die Datenbank (django-celery-beat) beschrieben. Die Anleitung behandelt Fehlerbehandlung mit Dead-Letter-Queues, Teststrategien (unitär, integriert, Retry-Tests) und Überwachungsmethoden wie Flower und Redis-CLI. Anti-Patterns wie das Übergeben von ORM-Instanzen oder nicht-idempotente Aufgaben werden hervorgehoben. Die Produktions-Checkliste gibt konkrete Einstellungen für Stabilität und Fairness vor. Unterstützte Plattformen sind primär Redis und RabbitMQ; die genannten Bibliotheken und Befehle sind für Celery 5.x und Django 4.x/5.x getestet. Der Skill ist besonders nützlich für Entwickler, die E-Mails, PDF-Generierung, API-Aufrufe oder andere zeitaufwändige Operationen aus dem Request-Zyklus auslagern möchten.

Funktioniert mit~Claude Code~Codex CLI~Cursor
npx skills add https://github.com/affaan-m/ECC/tree/main/skills/django-celery

In Ihrer bevorzugten KI fragen

Öffnet einen neuen Chat, in dem dieser Agent-Skill bereits geladen ist.

Dokumentation

Django + Celery Asynchrone Aufgabenmuster

Produktionsreife Muster für die Hintergrundaufgabenverarbeitung in Django mit Celery und Redis oder RabbitMQ.

Wann aktivieren

  • Hinzufügen von Hintergrundjobs oder asynchroner Verarbeitung zu einer Django-App
  • Implementieren von periodischen/geplanten Aufgaben
  • Auslagern von langsamen Operationen (E-Mails, PDF-Generierung, API-Aufrufe) aus dem Request-Zyklus
  • Einrichten von Celery Beat für cron-ähnliche Zeitplanung
  • Debuggen von Aufgabenfehlern, Wiederholungen oder Warteschlangenrückständen
  • Schreiben von Tests für Celery-Aufgaben

Projekteinrichtung

Installation

pip install 'celery[redis]' django-celery-results django-celery-beat

celery.py – App-Einstiegspunkt

# config/celery.py
import os
from celery import Celery

os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'config.settings.development')

app = Celery('myproject')
app.config_from_object('django.conf:settings', namespace='CELERY')
app.autodiscover_tasks()  # Findet tasks.py in jeder INSTALLED_APP

@app.task(bind=True, ignore_result=True)
def debug_task(self):
    print(f'Request: {self.request!r}')
# config/__init__.py
from .celery import app as celery_app

__all__ = ('celery_app',)

Django-Einstellungen

# config/settings/base.py

# Broker (Redis für Produktion empfohlen)
CELERY_BROKER_URL = env('CELERY_BROKER_URL', default='redis://localhost:6379/0')
CELERY_RESULT_BACKEND = env('CELERY_RESULT_BACKEND', default='django-db')

# Serialisierung
CELERY_ACCEPT_CONTENT = ['json']
CELERY_TASK_SERIALIZER = 'json'
CELERY_RESULT_SERIALIZER = 'json'

# Aufgabenverhalten
CELERY_TASK_TRACK_STARTED = True
CELERY_TASK_TIME_LIMIT = 30 * 60        # Hartes Limit: 30 Min
CELERY_TASK_SOFT_TIME_LIMIT = 25 * 60   # Weiches Limit: sendet SoftTimeLimitExceeded
CELERY_WORKER_PREFETCH_MULTIPLIER = 1   # Verhindert, dass Worker lange Aufgaben horten
CELERY_TASK_ACKS_LATE = True            # Bei Worker-Absturz erneut in die Warteschlange stellen

# Ergebnis-Persistenz
CELERY_RESULT_EXPIRES = 60 * 60 * 24   # Ergebnisse 24 Stunden behalten

# Beat-Scheduler (für periodische Aufgaben)
CELERY_BEAT_SCHEDULER = 'django_celery_beat.schedulers:DatabaseScheduler'

# Installierte Apps
INSTALLED_APPS += [
    'django_celery_results',
    'django_celery_beat',
]

Worker starten

# Worker starten (Entwicklung)
celery -A config worker --loglevel=info

# Beat-Scheduler starten (periodische Aufgaben)
celery -A config beat --loglevel=info --scheduler django_celery_beat.schedulers:DatabaseScheduler

# Kombinierter Worker + Beat (nur Entwicklung, niemals in Produktion)
celery -A config worker --beat --loglevel=info

# Produktion: mehrere Worker mit Parallelität
celery -A config worker --loglevel=warning --concurrency=4 -Q default,high_priority

Aufgabenentwurfsmuster

Einfache Aufgabe

# apps/notifications/tasks.py
from celery import shared_task
import logging

logger = logging.getLogger(__name__)

@shared_task(name='notifications.send_welcome_email')
def send_welcome_email(user_id: int) -> None:
    """Sende Willkommens-E-Mail an neu registrierten Benutzer."""
    from apps.users.models import User
    from apps.notifications.services import EmailService

    try:
        user = User.objects.get(pk=user_id)
    except User.DoesNotExist:
        logger.warning('send_welcome_email: Benutzer %s nicht gefunden', user_id)
        return  # Idempotent — nicht auslösen, Aufgabe bereits unmöglich auszuführen

    EmailService.send_welcome(user)
    logger.info('Willkommens-E-Mail an Benutzer %s gesendet', user_id)

Wiederholbare Aufgabe

@shared_task(
    bind=True,
    name='integrations.sync_to_crm',
    max_retries=5,
    default_retry_delay=60,       # Sekunden vor erstem Wiederholungsversuch
    autoretry_for=(ConnectionError, TimeoutError),
    retry_backoff=True,           # Exponentieller Backoff
    retry_backoff_max=600,        # Maximum 10 Minuten
    retry_jitter=True,            # Zufallsstreuung, um Überlastung zu vermeiden
)
def sync_contact_to_crm(self, contact_id: int) -> dict:
    """Sync Kontakt mit externem CRM mit Wiederholung bei vorübergehenden Fehlern."""
    from apps.crm.services import CRMClient

    try:
        result = CRMClient().sync(contact_id)
        return result
    except CRMClient.RateLimitError as exc:
        # Spezifische Verzögerung aus dem Antwort-Header
        raise self.retry(exc=exc, countdown=int(exc.retry_after))

Idempotentes Aufgabenmuster

Entwerfen Sie Aufgaben so, dass sie mit denselben Eingaben mehrmals sicher ausgeführt werden können:

@shared_task(name='orders.mark_shipped')
def mark_order_shipped(order_id: int, tracking_number: str) -> None:
    """Markiere Bestellung als versendet – sicher für mehrfache Ausführung."""
    from apps.orders.models import Order

    updated = Order.objects.filter(
        pk=order_id,
        status=Order.Status.PROCESSING,    # Schutz: nur aktualisieren, wenn noch nicht versendet
    ).update(
        status=Order.Status.SHIPPED,
        tracking_number=tracking_number,
    )

    if not updated:
        logger.info('mark_order_shipped: Bestellung %s bereits versendet oder nicht gefunden', order_id)

Aufgabe mit Soft-Time-Limit

from celery.exceptions import SoftTimeLimitExceeded

@shared_task(
    bind=True,
    name='reports.generate_pdf',
    soft_time_limit=120,
    time_limit=150,
)
def generate_pdf_report(self, report_id: int) -> str:
    """Generiere PDF-Bericht mit anmutiger Timeout-Behandlung."""
    from apps.reports.services import PDFGenerator

    try:
        path = PDFGenerator.build(report_id)
        return path
    except SoftTimeLimitExceeded:
        # Bereinige teilweise erstellte Dateien vor hartem Abbruch
        PDFGenerator.cleanup(report_id)
        raise

Aufgaben aufrufen

from datetime import timedelta
from django.utils import timezone

# Fire and forget (asynchron)
send_welcome_email.delay(user.pk)

# In der Zukunft planen
send_reminder.apply_async(args=[user.pk], countdown=3600)  # In 1 Stunde
send_reminder.apply_async(args=[user.pk], eta=timezone.now() + timedelta(days=1))

# Mit Warteschlangen-Routing ausführen
sync_contact_to_crm.apply_async(args=[contact.pk], queue='high_priority')

# Synchron ausführen (Tests / Debugging)
result = generate_pdf_report.apply(args=[report.pk])

Beat-Zeitplanung (Periodische Aufgaben)

Code-definierter Zeitplan

# config/settings/base.py
from celery.schedules import crontab

CELERY_BEAT_SCHEDULE = {
    'cleanup-expired-sessions': {
        'task': 'users.cleanup_expired_sessions',
        'schedule': crontab(hour=2, minute=0),   # Täglich um 2 Uhr
    },
    'sync-inventory': {
        'task': 'products.sync_inventory',
        'schedule': 60.0,                         # Alle 60 Sekunden
    },
    'weekly-digest': {
        'task': 'notifications.send_weekly_digest',
        'schedule': crontab(day_of_week='monday', hour=8, minute=0),
    },
}

Datenbank-definierter Zeitplan (über django-celery-beat)

# Periodische Aufgaben aus Django-Admin oder Code verwalten
from django_celery_beat.models import PeriodicTask, CrontabSchedule
import json

schedule, _ = CrontabSchedule.objects.get_or_create(
    hour='*/6', minute='0',
    timezone='UTC',
)

PeriodicTask.objects.update_or_create(
    name='Sync inventory every 6 hours',
    defaults={
        'crontab': schedule,
        'task': 'products.sync_inventory',
        'args': json.dumps([]),
        'enabled': True,
    }
)

Canvas: Verkettung und Gruppierung von Aufgaben

from celery import chain, group, chord

# Chain: Aufgaben nacheinander ausführen, Ergebnisse weitergeben
pipeline = chain(
    fetch_data.s(source_id),
    transform_data.s(),          # empfängt fetch_data-Ergebnis als erstes Argument
    load_to_warehouse.s(),
)
pipeline.delay()

# Group: Aufgaben parallel ausführen
parallel = group(
    send_welcome_email.s(user_id)
    for user_id in new_user_ids
)
parallel.delay()

# Chord: Parallele Aufgaben + Callback, wenn alle fertig sind
result = chord(
    group(process_chunk.s(chunk) for chunk in data_chunks),
    aggregate_results.s(),       # wird mit Liste der Chunk-Ergebnisse aufgerufen
)
result.delay()

Fehlerbehandlung und Dead Letter Queue

# apps/core/tasks.py
from celery.signals import task_failure

@task_failure.connect
def on_task_failure(sender, task_id, exception, args, kwargs, traceback, einfo, **kw):
    """Alle Aufgabenfehler an Sentry / Alerting loggen."""
    import sentry_sdk
    with sentry_sdk.new_scope() as scope:
        scope.set_context('celery', {
            'task': sender.name,
            'task_id': task_id,
            'args': args,
            'kwargs': kwargs,
        })
        sentry_sdk.capture_exception(exception)
# Fehlgeschlagene Aufgaben nach maximalen Wiederholungen an Dead-Letter-Warteschlange weiterleiten
@shared_task(
    bind=True,
    max_retries=3,
    name='payments.charge_card',
)
def charge_card(self, order_id: int) -> None:
    from apps.payments.models import Order, FailedCharge

    try:
        _do_charge(order_id)
    except Exception as exc:
        if self.request.retries >= self.max_retries:
            # In Dead-Letter-Tabelle für manuelle Überprüfung speichern
            FailedCharge.objects.create(
                order_id=order_id,
                error=str(exc),
                task_id=self.request.id,
            )
            return  # Nicht auslösen – Aufgabe dauerhaft fehlgeschlagen
        raise self.retry(exc=exc)

Testen von Celery-Aufgaben

Unit-Tests (Ohne Broker)

# tests/test_tasks.py
import pytest
from unittest.mock import patch, MagicMock
from apps.notifications.tasks import send_welcome_email

class TestSendWelcomeEmail:

    @pytest.mark.django_db
    def test_sends_email_to_existing_user(self, user):
        with patch('apps.notifications.services.EmailService') as mock_email:
            send_welcome_email(user.pk)
            mock_email.send_welcome.assert_called_once_with(user)

    @pytest.mark.django_db
    def test_skips_missing_user_gracefully(self):
        """Sollte nicht auslösen, wenn der Benutzer zwischen Einreihen und Ausführen gelöscht wurde."""
        send_welcome_email(99999)  # Nicht existierender Benutzer – darf nicht auslösen

Integrationstests mit CELERY_TASK_ALWAYS_EAGER

# config/settings/test.py
CELERY_TASK_ALWAYS_EAGER = True      # Aufgaben synchron in Tests ausführen
CELERY_TASK_EAGER_PROPAGATES = True  # Ausnahmen aus Aufgaben weiterleiten

# tests/test_integration.py
@pytest.mark.django_db
def test_registration_triggers_welcome_email(client):
    with patch('apps.notifications.services.EmailService') as mock_email:
        response = client.post('/api/users/', {
            'email': '[email protected]',
            'password': 'strongpass123',
        })

    assert response.status_code == 201
    mock_email.send_welcome.assert_called_once()

Testen von Wiederholungen

@pytest.mark.django_db
def test_task_retries_on_connection_error():
    with patch('apps.crm.services.CRMClient.sync') as mock_sync:
        mock_sync.side_effect = ConnectionError('timeout')

        with pytest.raises(ConnectionError):
            sync_contact_to_crm.apply(args=[1], throw=True)

        assert mock_sync.call_count == 1  # Nur erster Versuch bei eager

Überwachung

# Aktive Worker und Warteschlangen anzeigen
celery -A config inspect active
celery -A config inspect stats
celery -A config inspect reserved

# Warteschlangenlängen prüfen (Redis)
redis-cli llen celery

# Flower: Web-basierter Echtzeit-Monitor
pip install flower
celery -A config flower --port=5555

Anti-Patterns

# SCHLECHT: Modellinstanzen übergeben – sie könnten bei Ausführung veraltet sein
send_welcome_email.delay(user)        # Niemals ORM-Objekte übergeben
send_welcome_email.delay(user.pk)     # Immer Primärschlüssel übergeben

# SCHLECHT: Aufgaben synchron in Produktions-Views aufrufen
result = generate_report.apply()      # Blockiert den Request-Thread

# SCHLECHT: Nicht-idempotente Aufgabe ohne Schutzmechanismen
@shared_task
def charge_and_fulfill(order_id):
    order.charge()     # Kann zweimal belasten, wenn Aufgabe wiederholt wird!
    order.fulfill()

# GUT: Idempotent mit Status-Schutz
@shared_task
def charge_and_fulfill(order_id):
    order = Order.objects.select_for_update().get(pk=order_id)
    if order.status != Order.Status.PENDING:
        return  # Bereits verarbeitet
    order.charge()
    order.fulfill()

Produktions-Checkliste

PrüfungEinstellung
Worker-Neustart bei Absturzsupervisord oder systemd-Einheit
CELERY_TASK_ACKS_LATE = TrueAufgaben bei Worker-Absturz erneut in Warteschlange stellen
CELERY_WORKER_PREFETCH_MULTIPLIER = 1Faire Verteilung langer Aufgaben
Separate Warteschlangen pro Priorität-Q default,high_priority,low_priority
CELERY_TASK_SOFT_TIME_LIMIT gesetztAnmutiger Timeout vor hartem Abbruch
Sentry-IntegrationAlle task_failure-Signale erfassen
Flower oder anderer MonitorEinblick in Warteschlangentiefen
Beat läuft nur auf einem KnotenVerhindert doppelte Ausführung geplanter Aufgaben

Verwandte Skills

  • django-patterns – ORM, Service Layer und Projektstruktur
  • django-tdd – Testen von Django-Modellen, Views und Services
  • python-testing – pytest-Konfiguration und Fixtures

Individual skills in this repo

This repo contains 20 individual skills — each has its own dedicated page.

accessibility

Design, implement, and audit inclusive digital products using WCAG 2.2 Level AA. Use when building or auditing UI that must meet WCAG 2.2 Level AA, or when reviewing a change for keyboard, contrast, or screen-reader support.

affaan-m/content-engine

Create platform-native content systems for X, LinkedIn, TikTok, YouTube, newsletters, and repurposed multi-platform campaigns. Use when the user wants social posts, threads, scripts, content calendars, or one source asset adapted cleanly across platforms.

affaan-m/ECC

Multi-platform content distribution across X, LinkedIn, Threads, and Bluesky. Adapts content per platform using content-engine patterns. Never posts identical content cross-platform. Use when the user wants to distribute content across social platforms.

affaan-m/fal-ai-media

Unified media generation via fal.ai MCP — image, video, and audio. Covers text-to-image (Nano Banana), text/image-to-video (Seedance, Kling, Veo 3), text-to-speech (CSM-1B), and video-to-audio (ThinkSound). Use when the user wants to generate images, videos, or audio with AI.

affaan-m/manim-video

日本語翻訳:このファイルは manim-video 用の日本語翻訳が必要です

affaan-m/remotion-video-creation

Remotion のベストプラクティス - React で動画を作成する。3D、アニメーション、音声、字幕、チャート、トランジションなどをカバーするドメイン固有の29のルール。

affaan-m/video-editing

AI-assisted video editing workflows for cutting, structuring, and augmenting real footage. Covers the full pipeline from raw capture through FFmpeg, Remotion, ElevenLabs, fal.ai, and final polish in Descript or CapCut. Use when the user wants to edit video, cut footage, create vlogs, or build video content.

agent-architecture-audit

Full-stack diagnostic for agent and LLM applications. Audits the 12-layer agent stack for wrapper regression, memory pollution, tool discipline failures, hidden repair loops, and rendering corruption. Produces severity-ranked findings with code-first fixes. Essential for developers building agent applications, autonomous loops, or any LLM-powered feature. Use when an agent or LLM feature misbehaves and the failing layer is unknown, or before shipping an agent stack.

agent-eval

Head-to-head comparison of coding agents (Claude Code, Aider, Codex, etc.) on custom tasks with pass rate, cost, time, and consistency metrics. Use when choosing between coding agents, or when a change to an agent setup needs measured pass rate, cost, and time rather than an impression.

agent-harness-construction

Design and optimize AI agent action spaces, tool definitions, and observation formatting for higher completion rates. Use when defining or revising an agent

agentic-engineering

Operate as an agentic engineer using eval-first execution, decomposition, and cost-aware model routing. Use when planning or executing engineering work that agents will carry out end to end.

agentic-os

Build persistent multi-agent operating systems on Claude Code. Covers kernel architecture, specialist agents, slash commands, file-based memory, scheduled automation, and state management without external databases. Use when building a persistent multi-agent system on Claude Code with its own memory, commands, and scheduling.

agent-introspection-debugging

Structured self-debugging workflow for AI agent failures using capture, diagnosis, contained recovery, and introspection reports. Use when an agent run fails and you need a reproducible diagnosis instead of a retry.

agent-payment-x402

Add x402 payment execution to AI agents with per-task budgets, spending controls, and non-custodial wallets. Supports Base through agentwallet-sdk and X Layer through OKX Payments / OKX Agent Payments Protocol. Use when an agent must pay for something itself and needs per-task budgets, spending controls, and a non-custodial wallet.

agent-self-evaluation

Use after completing any non-trivial task. The agent self-rates its output on 5 axes — accuracy, completeness, clarity, actionability, conciseness — with concrete evidence per criterion. Produces a structured 1-5 scorecard with specific improvement suggestions.

agent-sort

Build an evidence-backed ECC install plan for a specific repo by sorting skills, commands, rules, hooks, and extras into DAILY vs LIBRARY buckets using parallel repo-aware review passes. Use when ECC should be trimmed to what a project actually needs instead of loading the full bundle.

ai-first-engineering

Engineering operating model for teams where AI agents generate a large share of implementation output. Use when setting team process, review gates, or ownership rules for a codebase largely written by agents.

ai-regression-testing

Regression testing strategies for AI-assisted development. Sandbox-mode API testing without database dependencies, automated bug-check workflows, and patterns to catch AI blind spots where the same model writes and reviews code. Use when adding regression coverage to AI-assisted code, or when the same model both wrote and reviewed a change.

android-clean-architecture

Clean Architecture patterns for Android and Kotlin Multiplatform projects — module structure, dependency rules, UseCases, Repositories, and data layer patterns. Use when structuring modules, layers, or data flow in an Android or KMP project.

angular-developer

Generates Angular code and provides architectural guidance. Trigger when creating projects, components, or services, or for best practices on reactivity (signals, linkedSignal, resource), forms, dependency injection, routing, SSR, accessibility (ARIA), animations, styling (component styles, Tailwind CSS), testing, or CLI tooling.

Verwandte Skills