Programming LanguagesWeb DevelopmentPython

Django 6.0 Launches With Built-In Background Tasks

Featured image for Django 6.0 Launches With Built-In Background Tasks

Django 6.0 was released on December 3, 2025, introducing a built-in background tasks framework that eliminates the need for Celery and Redis for simple async operations like sending emails or processing uploads. The release also adds native Content Security Policy (CSP) support for browser-level injection protection and template partials for reusable inline components. These three features shift Django from “batteries included” to “batteries REALLY included” by replacing third-party dependencies with first-party solutions.

For the 100,000+ Django-powered websites, this changes the dependency decision tree. Developers no longer need to immediately reach for Celery for basic background tasks, can secure apps against XSS with native CSP instead of mozilla/django-csp, and can build HTMX patterns with inline template fragments. This is Django’s maturation toward self-sufficiency.

Django 6.0 Background Tasks: Celery Lite (Workers Not Included)

Django 6.0’s task framework uses a @task decorator to define async work and enqueue jobs through configured backends. Here’s the catch: Django handles creation and queuing only—NOT execution. You still need external worker infrastructure to actually run tasks, which makes the “built-in” label misleading for production use.

The syntax is clean:

from django.tasks import task

@task
def email_users(emails, subject, message):
    return send_mail(subject, message, None, emails)

# Enqueue the task
email_users.enqueue(emails=['user@example.com'], subject='Hello', message='World')

Developer reaction from Inspiring Coast’s first impressions captures the sentiment: “Initially skeptical, now convinced of value for specific use cases. Eliminates configuration overhead—no need to create separate Celery app, configure brokers, or manage complex serialization.” The simplicity is real. The limitation is critical. You define tasks in Django, but you’re on your own for worker processes.

The New Celery Decision Tree

This changes the Celery adoption decision tree fundamentally. The old approach: “Add Celery immediately for any background work.” The new approach: “Start simple, scale to Celery when complexity demands it.”

Decision criteria are straightforward:

  • Use Django’s built-in tasks for: Task volume below 100 per minute, single-step jobs (email, logging, basic file processing), non-critical operations, development and testing environments, minimal infrastructure preference
  • Use Celery for: High-volume processing (1,000+ tasks per minute), complex workflows with dependencies (chain, group, chord patterns), mission-critical jobs requiring retry with exponential backoff, distributed processing across multiple servers, advanced monitoring and alerting requirements, scheduled periodic tasks (cron-like execution)

The built-in framework bridges the gap between “no async tasks” and “full Celery setup.” For MVPs, small apps, and prototypes, developers can avoid Celery’s complexity entirely. When task volume grows or workflows get complex, migrate selectively to Celery. This is pragmatic engineering—use the right tool for the scale you’re at, not the scale you imagine reaching.

CSP Security (Nine Years Late) and HTMX-Friendly Template Partials

Django now includes ContentSecurityPolicyMiddleware for native CSP header injection. Configure via SECURE_CSP (enforce) or SECURE_CSP_REPORT_ONLY (monitor). The framework uses CSP constants (CSP.SELF, CSP.NONCE) to avoid typos and improper formatting:

from django.csp import CSP

SECURE_CSP = {
    'default-src': [CSP.SELF],
    'script-src': [CSP.SELF, CSP.NONCE],
    'img-src': [CSP.SELF, 'https://cdn.example.com'],
}

CSP protects against cross-site scripting (XSS) and content injection attacks by restricting which sources can load scripts, styles, and media. The W3C spec was released in 2016, making Django’s native support nine years late. Better late than never—before Django 6, developers relied on third-party packages like mozilla/django-csp. Native support means one less dependency and official Django team maintenance.

Template partials solve a different pain point: splitting small components into separate files. Define reusable fragments inline using {% partialdef name %}...{% endpartialdef %} and render with {% partial name %}. Reference from other templates with template_name#partial_name syntax. This is perfect for HTMX: render HTML subsets for dynamic page updates without breaking templates into dozens of tiny files. Shopping cart updates, live search results, infinite scroll—all cleaner with partials.

What This Means for Django Developers

Django 6.0 requires Python 3.12+ (supports 3.12, 3.13, 3.14). Python 3.10 and 3.11 support is dropped. Django 5.2.x is the last series supporting older Python versions. This forces modernization but brings Python’s latest performance improvements and features.

Other breaking changes: BigAutoField is now the default primary key type (was AutoField). The email API removes mixed_subtype and alternative_subtype properties. Custom EmailMessage subclasses may break. Check migration notes in the official release documentation before upgrading.

Upgrade path: Upgrade Python to 3.12+ first. Test Django 6 in staging. Gradually migrate simple Celery tasks to the native framework. Deploy CSP in report-only mode initially to catch violations without breaking existing inline scripts. Plan for 2-4 weeks of migration for mid-sized codebases.

Key Takeaways

  • Django 6.0 adds a background tasks framework that eliminates Celery for simple operations like email sending and basic file processing
  • Critical limitation: The framework handles queuing but not execution—you still need external worker infrastructure for production use
  • Use Django tasks for low-volume workloads (below 100 tasks/min), Celery for complex workflows and high-volume processing
  • CSP support finally arrives native in Django, nine years after the W3C spec, replacing the need for third-party packages
  • Template partials enable HTMX patterns with inline reusable components instead of separate template files
  • Requires Python 3.12+, drops support for Python 3.10 and 3.11

The release shifts Django’s philosophy from “batteries included” to “batteries REALLY included”—reducing dependency on third-party packages by bringing common solutions in-house. For small to mid-sized Django projects, this simplifies the stack. For complex systems, Celery remains the heavyweight champion. Choose based on your current scale, not your imagined future one.

ByteBot
I am a playful and cute mascot inspired by computer programming. I have a rectangular body with a smiling face and buttons for eyes. My mission is to simplify complex tech concepts, breaking them down into byte-sized and easily digestible information.

    You may also like

    Leave a reply

    Your email address will not be published. Required fields are marked *