Skills DirectorySkills Directory
SkillsLearnSecurityCategoriesDocsBlogPro
Sign InSubmit Skill
Skills Directory

Security-tested agent skills for Claude, coding agents, and AI workflows.

Directory

  • Browse Skills
  • All Skills A–Z
  • Claude Skills
  • Claude Code Skills
  • Agent Skills
  • Categories
  • Authors
  • Submit a Skill

Learn

  • Learn Hub
  • Install Claude Skills
  • Write SKILL.md
  • Skills vs MCP
  • Directories Compared

Security

  • Security
  • Methodology
  • Secure Claude Skills
  • Security Badges
  • Chrome Extension
  • Skill Manager

Company

  • About
  • Community
  • Blog
  • API Docs
  • Advertise

2026 Skills Directory. All rights reserved.

ProTermsPrivacyRefunds
Back to skills

Django Celery

ASecurity

Use when integrating Celery with Django - task definition and calling, django-celery-beat scheduling, worker deployment, Flower monitoring, testing tasks, batch processing, or choosing between cron and beat

21 stars
0 votes
0 copies
0 views
Added 10/2/2026
databasespythongobashsqldjangotestinggitapidatabasebackend

Works with

api

Security Analysis

A96/100
mediumInstalls packages at runtime which could introduce malicious dependencies

Pro scans all 4 files and shows the line behind each finding

Scanned 10/2/2026

$npx -y skills add CodeAtCode/oss-ai-skills --skill django-celery --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Django Celery?

Add the live security badge to your README — it updates automatically with every re-scan.

Security grade badge for Django Celery
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/codeatcode-django-celery/badge)](https://www.skillsdirectory.com/skills/codeatcode-django-celery)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
Files
SKILL.md
---
name: django-celery
description: Use when integrating Celery with Django - task definition and calling, django-celery-beat scheduling, worker deployment, Flower monitoring, testing tasks, batch processing, or choosing between cron and beat
metadata:
  author: mte90
  version: 2.0.0
  tags:
    - python
    - django
    - celery
    - task-queue
    - periodic-tasks
    - django-celery-beat
---

# Django Celery Integration

Celery distributed task queue integrated with Django, including django-celery-beat for database-backed periodic task scheduling.

## Overview

This skill covers:
- Celery setup within a Django project
- Task definition and execution
- Periodic scheduling with `django-celery-beat`
- Monitoring and best practices

---

## Installation

```bash
pip install celery django-celery-beat redis
```

- **celery**: Task queue library
- **django-celery-beat**: Stores periodic task schedules in the Django database
- **redis**: Broker (recommended for production)

---

## Project Setup

### Celery App Configuration

Create `proj/celery.py` in your Django project directory (same level as `settings.py`):

```python
import os
from celery import Celery

os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'proj.settings')

app = Celery('proj')
app.config_from_object('django.conf:settings', namespace='CELERY')
app.autodiscover_tasks()
```

Update `proj/__init__.py`:

```python
from .celery import app as celery_app

__all__ = ('celery_app',)
```

### Django Settings

In `settings.py`:

```python
INSTALLED_APPS = [
    'django_celery_beat',
    'myapp',
]

CELERY_BROKER_URL = 'redis://localhost:6379/0'
CELERY_RESULT_BACKEND = 'redis://localhost:6379/1'
CELERY_ACCEPT_CONTENT = ['json']
CELERY_TASK_SERIALIZER = 'json'
CELERY_RESULT_SERIALIZER = 'json'
CELERY_TIMEZONE = 'Europe/Rome'
CELERY_ENABLE_UTC = True
CELERY_BEAT_SCHEDULER = 'django_celery_beat.schedulers:DatabaseScheduler'
CELERY_TASK_SOFT_TIME_LIMIT = 300
CELERY_TASK_TIME_LIMIT = 600
CELERY_TASK_DEFAULT_RETRY_DELAY = 60
CELERY_TASK_DEFAULT_MAX_RETRIES = 3
CELERY_TASK_ROUTES = {
    'myapp.tasks.send_email': {'queue': 'emails'},
    'myapp.tasks.process_video': {'queue': 'heavy'},
}
CELERY_WORKER_PREFETCH_MULTIPLIER = 1
CELERY_WORKER_MAX_TASKS_PER_CHILD = 1000
```

### Database Migration

```bash
python manage.py migrate django_celery_beat
```

---

## Anti-Patterns

### Database Pitfalls

**Passing QuerySets or model instances as task arguments** — The value is serialized at call time in the worker, which may evaluate against a different DB state. Always serialize IDs instead.

```python
# BAD: QuerySet evaluated in worker against stale state
@shared_task
def send_emails_to_users(users_qs):
    for user in users_qs:  # Evaluates in worker, may miss recent changes
        send_email(user)

# GOOD: serialize IDs, re-fetch in worker
@shared_task
def send_emails_to_user_ids(user_ids):
    for user in User.objects.filter(pk__in=user_ids):
        send_email(user)
```

**Calling `delay()`/`apply_async()` inside a transaction that later rolls back** — The task runs for a row that no longer exists. Use `transaction.on_commit` to defer task dispatch until the transaction commits.

```python
# BAD: task fires before transaction commits
@transaction.atomic
def create_order(request_data):
    order = Order.objects.create(**request_data)
    send_confirmation.delay(order.id)  # May run if outer transaction rolls back
    return order

# GOOD: defer until commit
@transaction.atomic
def create_order(request_data):
    order = Order.objects.create(**request_data)
    transaction.on_commit(lambda: send_confirmation.delay(order.id))
    return order
```

### Testing Pitfalls

**Assuming `CELERY_TASK_ALWAYS_EAGER` makes tests faithful** — Eager mode executes tasks synchronously in the test process. It does not exercise serialization, routing, retries, or worker behavior. It can produce false positives.

```python
# BAD: eager mode hides serialization bugs
@override_settings(CELERY_TASK_ALWAYS_EAGER=True)
def test_task_with_model(self):
    obj = MyModel.objects.create(name='test')
    my_task.delay(obj)  # Runs immediately, no serialization
    # Passes even if task can't serialize the object properly

# GOOD: test the function directly, mock apply_async
@mock.patch('myapp.tasks.my_task.apply_async')
def test_task_routing(self, mock_apply):
    my_task.delay(123)
    mock_apply.assert_called_once_with(args=[123], queue='default')
```

### Operational Pitfalls

**DB connections opened per task without cleanup** — Long-running workers accumulate stale connections. Use `close_old_connections()` at task start or configure `CELERY_WORKER_MAX_TASKS_PER_CHILD`.

```python
from django.db import close_old_connections

@shared_task
def long_running_task(data_id):
    close_old_connections()  # Drop stale DB connections
    # ... task work
```

**Timezone-aware datetimes not surviving naive serialization** — Naive serialization strips timezone info. Always use UTC and ensure serializers preserve timezone awareness.

```python
# BAD: naive datetime loses TZ
from datetime import datetime
send_report.delay(datetime.now())  # Loses timezone in JSON serializer

# GOOD: use UTC-aware datetime
from django.utils import timezone
send_report.delay(timezone.now())  # Preserves TZ through serialization
```

**Settings read at import time break `override_settings` in tests** — Access `django.conf.settings` at call time, not module load time.

```python
# BAD: settings read at import time
from django.conf import settings
BATCH_SIZE = settings.CELERY_BATCH_SIZE  # Fixed at import

@shared_task
def process_batch():
    for i in range(BATCH_SIZE):  # Can't be overridden in tests
        ...

# GOOD: read at call time
@shared_task
def process_batch():
    from django.conf import settings
    batch_size = settings.CELERY_BATCH_SIZE  # Read fresh each call
    for i in range(batch_size):
        ...
```

---

## Testing

### Testing Task Functions Directly

Call the underlying task function directly instead of using `delay()` or `apply_async()`. This tests the actual logic without Celery machinery.

```python
from django.test import TestCase
from myapp.tasks import send_welcome_email

class TaskFunctionTests(TestCase):
    def test_send_welcome_email_logic(self):
        user = User.objects.create_user(username='test', email='test@example.com')
        
        # Call the function directly, bypassing Celery
        send_welcome_email(user.id)
        
        # Assert on side effects
        self.assertEqual(len(mail.outbox), 1)
        self.assertEqual(mail.outbox[0].to, ['test@example.com'])
```

### Mocking `apply_async` to Assert Task Dispatch

Mock `apply_async` to verify that tasks are scheduled with correct arguments and routing.

```python
from unittest import mock
from django.test import TestCase
from myapp.tasks import process_upload

class TaskDispatchTests(TestCase):
    @mock.patch('myapp.tasks.process_upload.apply_async')
    def test_process_upload_scheduled_with_queue(self, mock_apply):
        process_upload.delay(123, queue='heavy')
        
        mock_apply.assert_called_once_with(args=[123], queue='heavy')
    
    @mock.patch('myapp.tasks.send_confirmation.apply_async')
    def test_task_scheduled_after_commit(self, mock_apply):
        with transaction.atomic():
            order = Order.objects.create(total=100)
            transaction.on_commit(lambda: send_confirmation.delay(order.id))
        
        # Verify on_commit callback scheduled the task
        mock_apply.assert_called_once()
```

### Testing Retries Deterministically

Test retry behavior by mocking the retry mechanism and asserting on the `Retry` exception.

```python
from unittest import mock
from celery.exceptions import Retry
from django.test import TestCase
from myapp.tasks import fetch_external_data

class TaskRetryTests(TestCase):
    @mock.patch('myapp.tasks.fetch_external_data.retry')
    def test_fetch_external_data_retries_on_connection_error(self, mock_retry):
        with mock.patch('myapp.tasks.fetch_external_data', side_effect=ConnectionError('timeout')):
            with self.assertRaises(Retry):
                fetch_external_data('http://example.com')
        
        mock_retry.assert_called_once()
    
    def test_fetch_external_data_succeeds_without_retry(self):
        with mock.patch('myapp.tasks.requests.get') as mock_get:
            mock_get.return_value.json.return_value = {'data': 'value'}
            result = fetch_external_data('http://example.com')
        
        self.assertEqual(result, {'data': 'value'})
```

### When Eager Mode Produces False Positives

Eager mode runs tasks synchronously in the test process. It does not test:
- Serialization/deserialization of task arguments
- Task routing and queue configuration
- Retry behavior with actual backoff
- Worker concurrency issues

```python
# FALSE POSITIVE: eager mode passes, but task fails in production
@override_settings(CELERY_TASK_ALWAYS_EAGER=True)
def test_model_instance_passed(self):
    obj = MyModel.objects.create(name='test')
    # This passes in eager mode but fails in production because
    # model instances can't be serialized by JSON serializer
    my_task.delay(obj)  # ERROR: Object of type MyModel is not JSON serializable

# CORRECT: test serialization explicitly
def test_task_argument_serialization(self):
    from celery.backends.base import BaseBackend
    
    obj = MyModel.objects.create(name='test')
    
    # Verify the argument can be serialized
    backend = BaseBackend(None)
    with self.assertRaises(TypeError):
        backend.encode({'obj': obj})  # Should fail for model instances
    
    # Verify ID serializes correctly
    result = backend.encode({'obj_id': obj.id})  # Should pass
    self.assertIn('obj_id', result[0])
```

---

## Deep Dives

Load these reference files on demand for detailed patterns:

- **Tasks & Calling** — `references/tasks.md` — Defining tasks, task options, signatures (chain/group/chord), result checking
- **Scheduling & Workers** — `references/scheduling-workers.md` — django-celery-beat, systemd deployment, cron vs beat decision guide
- **Monitoring & Batch** — `references/monitoring-batch.md` — Flower, health checks, batch processing with savepoints

---

## Ecosystem

### Monitoring

- **flower** (https://github.com/mher/flower) — Web-based Celery cluster admin and monitoring. Real-time task progress, worker stats, task history, broker metrics.
- **celery-exporter** (https://github.com/danihodovic/celery-exporter) — Prometheus metrics exporter for Celery. Exposes task durations, queue lengths, worker status for Grafana dashboards.

### Results & Backends

- **django-celery-results** (https://github.com/celery/django-celery-results) — Django ORM-based result backend. Store task results in Django database instead of Redis/RabbitMQ.

### Cache/Broker Companion

- **django-redis** (https://github.com/jazzband/django-redis) — Full-featured Redis cache backend for Django. Can be used as Celery broker companion for unified Redis infrastructure.

### Alternatives

| Library | Problem it solves | When to choose over Celery |
|---------|-------------------|----------------------------|
| **django-q2** (https://github.com/django-q2/django-q2) | Simple task queue with built-in scheduler, no external broker needed | You want periodic tasks without Redis/RabbitMQ; prefer Django-native scheduler |
| **django-dramatiq** (https://github.com/Bogdanp/django_dramatiq) | High-performance task queue with better retry semantics | You need message acknowledgment guarantees, better observability than Celery |
| **huey** (https://github.com/coleifer/huey) | Minimal task queue, works with SQLite/Redis | Tiny projects, no external broker infrastructure, simple scheduling needs |
| **django-tasks** (https://github.com/realOrangeOne/django-tasks) | Django DEP 14 reference implementation | Evaluating future Django standard task queue API; experimental |

**Selection criteria:** If you already use Celery for a task queue, stick with it. Choose an alternative only if: (1) you need zero external dependencies (huey, django-q2), (2) you require stronger message guarantees (dramatiq), or (3) you're prototyping against future Django standards (django-tasks).

---

## References

- **Celery Docs**: https://docs.celeryq.dev/en/stable/
- **django-celery-beat**: https://django-celery-beat.readthedocs.io/
- **Celery with Django**: https://docs.celeryq.dev/en/stable/django/first-steps-with-django.html
- **Flower**: https://github.com/mher/flower

Attribution

CodeAtCodeCodeAtCode
View sourceSee grades on GitHubMore from CodeAtCode →
SSkills DirectorySkills Directory

Ship a skill? Prove it's safe.

Free 120-pattern security scan, letter grade, and an embeddable README badge.

Submit a skill

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments (0)

No comments yet. Be the first to comment!

SSkills DirectorySkills Directory

Ship a skill? Prove it's safe.

Free 120-pattern security scan, letter grade, and an embeddable README badge.

Submit a skill

Related Skills

Mysql Best Practices

MySQL development best practices for schema design, query optimization, and database administration

2481 votes

Jpa Patterns

Spring Boot中的JPA/Hibernate实体设计、关系、查询优化、事务、审计、索引、分页和连接池模式。

2456590 votes

Clickhouse Io

ClickHouse数据库模式、查询优化、分析和数据工程最佳实践,适用于高性能分析工作负载。

2456590 votes

Postgres Patterns

基于Supabase最佳实践的PostgreSQL数据库模式,用于查询优化、架构设计、索引和安全。

2456590 votes

Sql Pro

Master modern SQL with cloud-native databases, OLTP/OLAP

458250 votes
View all in databases →