Django 6.0 was released on December 3, 2025, marking 20 years since Django was first created. This milestone release brings several highly anticipated features that the community has been waiting for. Let’s dive into everything new.
Python Support
Django 6.0 requires Python 3.12 or higher (3.12, 3.13, or 3.14). This is a significant change from Django 5.2, which supported Python 3.10 and 3.11.
# Check your Python version |
Major New Features
1. Background Tasks Framework
This is the biggest addition to Django 6.0. Django now includes a built-in Tasks framework for running code outside the HTTP request-response cycle. No more mandatory Celery setup for simple background tasks!
Basic Usage
from django.tasks import task |
Task Configuration Options
from django.tasks import task |
Settings Configuration
Configure backends in settings.py:
TASKS = { |
Built-in Backends:
ImmediateBackend- Runs tasks synchronously (development/testing)DummyBackend- Records tasks without executing (testing)
For production, you’ll need a third-party backend that connects to a task runner like Redis, RabbitMQ, or a database-backed queue.
Getting Task Results
from django.tasks import task |
2. Template Partials
Template partials allow you to define reusable fragments within a single template file. No more creating dozens of tiny include files!
Defining and Using Partials
{# templates/components.html #} |
Including Partials from Other Templates
The new template_name#partial_name syntax works with {% include %}, get_template(), and render():
{# templates/page.html #} |
# In Python code |
Migration from django-template-partials
If you were using the third-party django-template-partials package, Django provides a migration guide in the official docs.
3. Content Security Policy (CSP) Support
Built-in CSP support makes it easier to protect your application against XSS attacks.
Basic Configuration
# settings.py |
Using Nonces in Templates
Add the context processor to enable nonce support:
# settings.py |
{# In your template #} |
CSP Constants
Django provides constants for common CSP values:
from django.utils.csp import CSP |
4. Modernized Email API
Django now uses Python’s modern email.message.EmailMessage class instead of the legacy MIME classes.
What’s New
from django.core.mail import EmailMessage |
Breaking Changes
If you have custom EmailMessage subclasses, review your overrides:
# These properties are REMOVED in Django 6.0: |
Other Notable Features
New Template Variables
forloop.length in For Loops
{% for item in items %} |
AsyncPaginator
New async-compatible paginator for async views:
from django.core.paginator import AsyncPaginator |
StringAgg on All Databases
StringAgg aggregate is no longer PostgreSQL-only:
from django.db.models import Value |
Aggregate Ordering
Aggregates now support order_by:
from django.db.models import F |
GeneratedField Refresh
Generated fields and fields with expressions are now automatically refreshed after save() on supported backends (PostgreSQL, SQLite, Oracle):
class Product(models.Model): |
BigAutoField Default
New projects now use BigAutoField (64-bit) by default instead of AutoField (32-bit):
# If you need the old behavior, set explicitly: |
Admin Improvements
- Font Awesome Free (v6.7.2) icons
- Distinct icons for
DEBUGandINFOmessage levels - New
AdminSite.password_change_formfor customization
GIS Enhancements
GEOSGeometry.hasmproperty for M dimension detectionRotatedatabase functionBaseGeometryWidget.base_layerfor custom map providers- New lookups and functions for MariaDB 12.0.1+
Backwards Incompatible Changes
Python Version
- Minimum Python 3.12 - Drop support for Python 3.10 and 3.11
Database Support
- MariaDB 10.5 dropped - Minimum is now MariaDB 10.6
ORM Changes
Custom lookups and expressions must return params as tuples, not lists:
# Before (Django 5.x) |
Email API Changes
The following are removed from EmailMessage:
mixed_subtypepropertyalternative_subtypepropertyencodingproperty
Deprecations
Email Function Arguments
All optional parameters must use keyword arguments:
# Deprecated (positional) |
URL Handling
Default protocol in urlize and urlizetrunc changes from HTTP to HTTPS:
# To prepare, set in settings.py: |
ADMINS/MANAGERS Format
Tuples are deprecated, use email strings:
# Deprecated |
Upgrading to Django 6.0
Step-by-Step Guide
Upgrade Python first:
# Ensure Python 3.12+
python --versionUpdate Django:
pip install Django==6.0
Run checks:
python manage.py check
python manage.py makemigrationsReview deprecation warnings:
python -Wa manage.py test
Update settings:
# settings.py
# If you need 32-bit auto fields (legacy)
DEFAULT_AUTO_FIELD = "django.db.models.AutoField"
# Prepare for HTTPS default in urlize
URLIZE_ASSUME_HTTPS = TrueTest thoroughly before deploying to production.
Quick Reference
| Feature | Import/Setting |
|---|---|
| Background Tasks | from django.tasks import task |
| Template Partials | partialdef, partial template tags |
| CSP Middleware | django.middleware.security.ContentSecurityPolicyMiddleware |
| CSP Settings | SECURE_CSP, SECURE_CSP_REPORT_ONLY |
| Async Paginator | from django.core.paginator import AsyncPaginator |
Conclusion
Django 6.0 is a landmark release celebrating 20 years of Django. The built-in background tasks framework eliminates the need for Celery in many use cases. Template partials make templates more maintainable. CSP support improves security out of the box. And the modernized email API brings Django up to date with Python’s latest standards.
The transition from Django 5.x should be smooth for most projects, with the main consideration being the Python 3.12+ requirement.