--- name: django-6-upgrade description: "⚠️ DRAFT/SPEKULATIV - Django 6.0 ist noch nicht released! Diese Dokumentation basiert auf erwarteten Features. Für aktuelle Upgrades (4.2 → 5.2) bitte offizielle Django Docs verwenden." argument-hint: [--check-only | --full-upgrade] allowed-tools: Read, Write, Edit, Glob, Grep, Bash, WebFetch --- > **⚠️ DRAFT - NICHT PRODUKTIONSREIF** > > Django 6.0 ist noch nicht released (Stand: Februar 2026). > Diese Dokumentation basiert auf Spekulationen und erwarteten Features. > Features wie "Background Tasks Framework", "Template Partials", "CSP Middleware" sind NICHT bestätigt. > > **Für aktuelle Upgrades bitte offizielle Django Dokumentation verwenden:** > - Django 4.2 → 5.0: https://docs.djangoproject.com/en/5.0/releases/5.0/ > - Django 5.0 → 5.1: https://docs.djangoproject.com/en/5.1/releases/5.1/ > - Django 5.1 → 5.2: https://docs.djangoproject.com/en/5.2/releases/5.2/ # Django 5.2 → 6.0 Upgrade Guide (DRAFT/SPEKULATIV) Comprehensive guide for upgrading Django projects from 5.2 LTS to 6.0, covering breaking changes, removed deprecations, and new features like background tasks, template partials, and CSP support. ## When to Use - Upgrading a Django 5.2 project to Django 6.0 - Checking compatibility before upgrading - Fixing deprecation warnings from Django 5.x - Adopting new Django 6.0 features (CSP, template partials, background tasks) ## Prerequisites - **Python 3.12+** required (Django 6.0 drops Python 3.10/3.11 support) - Django 5.2 project with passing tests - All third-party packages compatible with Django 6.0 ## Upgrade Checklist ### Phase 1: Pre-Upgrade Preparation ```bash # 1. Check Python version (must be 3.12+) python --version # 2. Run deprecation warnings check python -Wd manage.py check python -Wd manage.py test # 3. Run django-upgrade tool (automatic fixes) pip install django-upgrade django-upgrade --target-version 6.0 **/*.py ``` ### Phase 2: Breaking Changes #### 1. Python Version Requirement ```python # pyproject.toml or setup.py # BEFORE python_requires = ">=3.10" # AFTER python_requires = ">=3.12" ``` #### 2. DEFAULT_AUTO_FIELD Change Django 6.0 defaults to `BigAutoField`. If your project already sets this, you can remove it: ```python # settings.py # REMOVE this line if it's set to BigAutoField (now the default) # DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField' # KEEP if using a different field type DEFAULT_AUTO_FIELD = 'django.db.models.AutoField' # Keep if intentional ``` **WARNING**: Removing `DEFAULT_AUTO_FIELD` when set to `AutoField` will cause migrations! #### 3. Database Backend Changes ```python # BEFORE (Django 5.2) class MyDatabaseOperations(DatabaseOperations): def return_insert_columns(self, fields): ... def fetch_returned_insert_rows(self, cursor): ... def fetch_returned_insert_columns(self, cursor): ... # AFTER (Django 6.0) class MyDatabaseOperations(DatabaseOperations): def returning_columns(self, fields): # Renamed ... def fetch_returned_rows(self, cursor): # Renamed ... # fetch_returned_insert_columns is REMOVED ``` #### 4. Email API Changes ```python # BEFORE (Django 5.2) from django.core.mail import BadHeaderError, SafeMIMEText, SafeMIMEMultipart from django.core.mail.message import sanitize_address, forbid_multi_line_headers try: send_mail(subject, message, from_email, [to_email]) except BadHeaderError: pass # AFTER (Django 6.0) # BadHeaderError → ValueError # SafeMIMEText/SafeMIMEMultipart → Use Python's email.mime classes directly # sanitize_address/forbid_multi_line_headers → Removed try: send_mail(subject, message, from_email, [to_email]) except ValueError: # Replaces BadHeaderError pass ``` #### 5. ADMINS/MANAGERS Settings ```python # BEFORE (Django 5.2) - Deprecated tuple format ADMINS = [ ('Admin Name', 'admin@example.com'), ('Another Admin', 'another@example.com'), ] # AFTER (Django 6.0) - Email strings only ADMINS = [ 'admin@example.com', 'another@example.com', ] # Same for MANAGERS MANAGERS = [ 'manager@example.com', ] ``` #### 6. BaseConstraint Positional Arguments ```python # BEFORE (Django 5.2) class MyConstraint(BaseConstraint): def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) # AFTER (Django 6.0) - Positional args removed class MyConstraint(BaseConstraint): def __init__(self, *, name, violation_error_code=None, violation_error_message=None): super().__init__( name=name, violation_error_code=violation_error_code, violation_error_message=violation_error_message, ) ``` #### 7. ModelAdmin.lookup_allowed() Signature ```python # BEFORE (Django 5.2) class MyModelAdmin(admin.ModelAdmin): def lookup_allowed(self, lookup, value): return super().lookup_allowed(lookup, value) # AFTER (Django 6.0) - request is required class MyModelAdmin(admin.ModelAdmin): def lookup_allowed(self, lookup, value, request): # request added return super().lookup_allowed(lookup, value, request) ``` #### 8. Prefetch QuerySet Method ```python # BEFORE (Django 5.2) class MyManager(Manager): def get_prefetch_queryset(self, instances, queryset=None): ... # AFTER (Django 6.0) class MyManager(Manager): def get_prefetch_querysets(self, instances, querysets=None): # Plural ... ``` #### 9. Form Renderer Changes ```python # BEFORE (Django 5.2) - Transitional renderers from django.forms.renderers import DjangoDivFormRenderer, Jinja2DivFormRenderer # AFTER (Django 6.0) - Removed, use standard renderers from django.forms.renderers import DjangoTemplates, Jinja2 # Or the new default which uses div-based rendering ``` #### 10. StringAgg Import Location ```python # BEFORE (Django 5.2) - PostgreSQL only from django.contrib.postgres.aggregates import StringAgg # AFTER (Django 6.0) - Available for all databases from django.db.models import StringAgg # Note: Delimiter must be wrapped in Value() for string literals from django.db.models import Value result = MyModel.objects.aggregate( names=StringAgg('name', delimiter=Value(', ')) ) ``` ### Phase 3: New Features to Adopt #### 1. Content Security Policy (CSP) ```python # settings.py MIDDLEWARE = [ ... 'django.middleware.security.ContentSecurityPolicyMiddleware', # Add ... ] # CSP Configuration SECURE_CSP = { 'default-src': ["'self'"], 'script-src': ["'self'", "'nonce'"], # 'nonce' enables nonce support 'style-src': ["'self'", "'unsafe-inline'"], 'img-src': ["'self'", 'data:', 'https:'], 'font-src': ["'self'"], 'connect-src': ["'self'"], 'frame-ancestors': ["'none'"], } # Report-only mode for testing SECURE_CSP_REPORT_ONLY = { 'default-src': ["'self'"], 'report-uri': '/csp-report/', } # templates/base.html TEMPLATES = [ { ... 'OPTIONS': { 'context_processors': [ ... 'django.template.context_processors.csp', # Add for nonce support ], }, }, ] ``` ```html ``` #### 2. Template Partials ```html {% partialdef card %}
{{ content }}