# Django 6.0: Composite Primary Keys, Background Tasks und die wichtigsten Neuerungen für 2026 > Django 6.0 erweitert das Framework um ein integriertes Background-Tasks-Framework, Template Partials und native CSP-Middleware. Zusammen mit Composite Primary Keys aus Django 5.2 bietet das Ökosystem 2026 leistungsfähigere Werkzeuge für produktionsreife Webanwendungen. - Published: 2026-06-09 - Updated: 2026-06-09 - Author: SharpSkill - Tags: django, python, composite-primary-keys, background-tasks, django-6 - Reading time: 8 min --- Django 6.0 markiert einen substanziellen Entwicklungsschritt für das meistgenutzte Python-Webframework. Mit der Veröffentlichung im Dezember 2025 erhielt der Django-Kern ein integriertes Background-Tasks-Framework, Template Partials zur Strukturierung wiederverwendbarer Template-Fragmente und eine native Content-Security-Policy-Middleware. In Verbindung mit den Composite Primary Keys, die bereits in Django 5.2 Einzug hielten, steht Entwicklern im Jahr 2026 ein deutlich ausgereifteres Gesamtpaket für anspruchsvolle Webanwendungen zur Verfügung. > **Django-Versionszeitplan für 2026** > > Django 5.2 LTS (April 2025) führte Composite Primary Keys ein. Django 6.0 (Dezember 2025) ergänzte Background Tasks, Template Partials und CSP-Middleware. Django 6.1 befindet sich aktuell in aktiver Entwicklung und wird voraussichtlich Field Fetch Modes sowie weitere ORM-Optimierungen mitbringen. ## Composite Primary Keys mit CompositePrimaryKey Über 18 Jahre lang erzwang Django für jedes Modell einen einspaltigen Primärschlüssel. Django 5.2 beseitigte diese langjährige Einschränkung durch die Einführung der Klasse `CompositePrimaryKey`, die mehrspaltige Primärschlüssel direkt auf ORM-Ebene ermöglicht. Zusammengesetzte Primärschlüssel eliminieren die Notwendigkeit künstlicher `AutoField`-Spalten auf Verknüpfungstabellen und auf allen Modellen, deren natürlicher Schlüssel aus mehreren Spalten besteht. Die Datenbank übernimmt die Eindeutigkeitsgarantie auf Primärschlüsselebene, was sowohl den Speicherbedarf reduziert als auch die Abfrageperformance bei indizierten Zugriffen verbessert. ```python # models.py from django.db import models class Product(models.Model): name = models.CharField(max_length=100) sku = models.CharField(max_length=20, unique=True) class Warehouse(models.Model): code = models.CharField(max_length=10, primary_key=True) location = models.CharField(max_length=200) class Inventory(models.Model): pk = models.CompositePrimaryKey("product_id", "warehouse_id") product = models.ForeignKey(Product, on_delete=models.CASCADE) warehouse = models.ForeignKey(Warehouse, on_delete=models.CASCADE) quantity = models.PositiveIntegerField(default=0) last_restocked = models.DateTimeField(auto_now=True) ``` Das Modell `Inventory` erzeugt auf Datenbankebene einen Constraint `PRIMARY KEY (product_id, warehouse_id)`. Eine zusätzliche `id`-Spalte wird dabei nicht generiert. Dieser Ansatz entspricht dem etablierten Muster in relationalen Datenbanken, bei dem die Kombination zweier Fremdschlüssel die natürliche Identität eines Datensatzes abbildet. ### Abfragen mit zusammengesetzten Schlüsseln Zusammengesetzte Primärschlüssel werden in Python als Tupel repräsentiert. Filterung, Zugriff und Zuweisung erfolgen durchgehend über diese Tupel-Schnittstelle. ```python # views.py from .models import Inventory, Product, Warehouse # Create records laptop = Product.objects.create(name="Laptop Pro", sku="LP-001") warehouse_a = Warehouse.objects.create(code="WH-A", location="Berlin") item = Inventory.objects.create( product=laptop, warehouse=warehouse_a, quantity=50 ) # Access the composite pk as a tuple print(item.pk) # (1, "WH-A") # Filter by composite pk result = Inventory.objects.filter(pk=(1, "WH-A")).first() # Assign a composite pk directly new_item = Inventory(pk=(2, "WH-B")) print(new_item.product_id) # 2 print(new_item.warehouse_id) # "WH-B" ``` Drei aktuelle Einschränkungen verdienen besondere Aufmerksamkeit: `ForeignKey` kann nicht direkt auf ein Modell mit zusammengesetztem Primärschlüssel verweisen (stattdessen muss `ForeignObject` verwendet werden), die Django-Admin-Oberfläche unterstützt Modelle mit zusammengesetzten Schlüsseln noch nicht vollständig, und die nachträgliche Migration zwischen einfachen und zusammengesetzten Schlüsseln auf bereits existierenden Tabellen erfordert manuelles SQL. ## Integriertes Background-Tasks-Framework in Django 6.0 Bis Django 6.0 war die Ausführung von Code außerhalb des Request-Response-Zyklus ausschließlich über Drittanbieter-Bibliotheken wie Celery, Django-Q oder vergleichbare Task-Queues möglich. Django 6.0 schließt diese Lücke mit einem nativen Tasks-Framework, das Aufgabendefinition und Einreihung direkt im Framework-Kern bereitstellt. Der Dekorator `@task` markiert eine beliebige Funktion als einreihbar. Durch den Aufruf von `.enqueue()` auf der dekorierten Funktion wird die Aufgabe an ein konfiguriertes Backend zur asynchronen Ausführung übergeben. Das Framework trennt die Aufgabendefinition sauber von der Aufgabenausführung: Django verwaltet die Warteschlange, während ein separater Worker-Prozess die tatsächliche Verarbeitung übernimmt. ```python # tasks.py from django.tasks import task from django.core.mail import send_mail @task def send_welcome_email(user_email, username): """Send a welcome email after user registration.""" send_mail( subject="Welcome to the platform", message=f"Hello {username}, your account is ready.", from_email=None, # uses DEFAULT_FROM_EMAIL recipient_list=[user_email], ) return f"Email sent to {user_email}" @task def generate_report(report_id, format="pdf"): """Generate an export report asynchronously.""" from .services import ReportService report = ReportService.generate(report_id, format=format) return report.file_path ``` ```python # views.py from .tasks import send_welcome_email, generate_report def register_user(request): # ... user creation logic ... # Enqueue the task for background execution send_welcome_email.enqueue( user_email=user.email, username=user.username ) return redirect("dashboard") def export_view(request, report_id): generate_report.enqueue(report_id=report_id, format="csv") return JsonResponse({"status": "processing"}) ``` Die Einstellung `TASKS` in der `settings.py` konfiguriert das gewählte Backend. Django liefert zwei integrierte Backends mit: Das Immediate-Backend führt Tasks synchron innerhalb desselben Prozesses aus und eignet sich für die lokale Entwicklung. Das Dummy-Backend verwirft sämtliche eingereihten Tasks und dient zum Testen von Code, der Tasks einreiht, ohne deren tatsächliche Ausführung auszulösen. Für Produktionsumgebungen ist ein Drittanbieter-Backend oder eine eigene Implementierung erforderlich, die an einen Message Broker wie Redis oder RabbitMQ angebunden wird. > **Background Tasks im Vergleich zu Celery** > > Das integrierte Tasks-Framework von Django deckt einfache Anwendungsfälle ab: Fire-and-Forget-Aufgaben, E-Mail-Versand und Berichtsgenerierung. Für erweiterte Funktionalität wie Task-Chaining, periodische Ausführung (Cron-artige Zeitpläne), Rate Limiting oder Result Backends bleibt Celery die etablierte Standardlösung. Beide Ansätze können in einem Projekt koexistieren. ## Template Partials für wiederverwendbare Fragmente Django 6.0 führt die Template-Tags `{% partialdef %}` und `{% partial %}` ein. Diese ermöglichen die Definition benannter, wiederverwendbarer Template-Fragmente innerhalb einer einzigen Datei und reduzieren die Notwendigkeit zahlreicher kleiner Include-Dateien, die über das Template-Verzeichnis verstreut liegen. ```html {% partialdef product_card %}

{{ product.name }}

{{ product.price|floatformat:2 }} EUR

{% if product.in_stock %}In Stock{% else %}Sold Out{% endif %}
{% endpartialdef %} {% partialdef product_row %} {{ product.name }} {{ product.price|floatformat:2 }} EUR {{ product.quantity }} {% endpartialdef %} ``` ```html {% extends "base.html" %} {% block content %}
{% for product in products %} {% include "components/cards.html#product_card" %} {% endfor %}
{% endblock %} ``` Der zentrale Vorteil liegt in der Gruppierung zusammengehöriger Darstellungsvarianten. Statt separate Dateien für `_product_card.html` und `_product_row.html` anzulegen, fasst eine einzige `cards.html`-Datei sämtliche Darstellungsformen eines Konzepts zusammen. Der Hash-Selektor (`components/cards.html#product_card`) adressiert das gewünschte Fragment präzise. Diese Organisationsform verbessert die Wartbarkeit erheblich, insbesondere in umfangreichen Projekten mit zahlreichen wiederverwendbaren UI-Bausteinen. Template Partials harmonieren zudem hervorragend mit Bibliotheken wie HTMX, die auf partiellem HTML-Austausch basieren. Der Server kann gezielt einzelne Seitenfragmente zurückgeben, ohne das vollständige Template rendern zu müssen. ## Native Content-Security-Policy-Middleware Django 6.0 integriert CSP-Unterstützung direkt in den Framework-Kern durch die neue `ContentSecurityPolicyMiddleware`. Zuvor war für diese Funktionalität das Drittanbieter-Paket `django-csp` erforderlich. ```python # settings.py from django.utils.csp import CSP MIDDLEWARE = [ "django.middleware.security.SecurityMiddleware", "django.middleware.security.ContentSecurityPolicyMiddleware", # ... other middleware ] SECURE_CSP = { "default-src": [CSP.SELF], "script-src": [CSP.SELF, CSP.NONCE], "style-src": [CSP.SELF, "https://fonts.googleapis.com"], "img-src": [CSP.SELF, "https:", "data:"], "font-src": [CSP.SELF, "https://fonts.gstatic.com"], "connect-src": [CSP.SELF], } # Report-only mode for testing (does not block, only reports violations) SECURE_CSP_REPORT_ONLY = { "default-src": [CSP.SELF], "report-uri": ["/csp-report/"], } ``` Die Integration in die bestehende Security-Middleware-Kette erfolgt nahtlos. Der Wert `CSP.NONCE` generiert automatisch einen kryptographisch sicheren Nonce-Wert pro Request, der in Templates über das Kontextattribut `{{ request.csp_nonce }}` zugänglich ist. Besonders wertvoll ist der Report-Only-Modus: CSP-Verstöße werden protokolliert, aber nicht blockiert. Dadurch lässt sich eine CSP-Konfiguration schrittweise in Produktionsumgebungen testen, ohne den laufenden Betrieb zu beeinträchtigen. Erst nach erfolgreicher Validierung wird die Richtlinie in den erzwingenden Modus überführt. ## Weitere nennenswerte Änderungen in Django 6.0 Über die Hauptfeatures hinaus bringt Django 6.0 eine Reihe von Änderungen, die den Entwicklungsalltag spürbar beeinflussen. **BigAutoField als Standard-Primärschlüssel.** Neue Projekte verwenden ab sofort `BigAutoField` (64-Bit) anstelle von `AutoField` (32-Bit) für automatisch generierte Primärschlüssel. Diese Änderung beseitigt potenzielle Überlaufprobleme bei Tabellen mit hohem Datenvolumen. Bestehende Projekte, die `DEFAULT_AUTO_FIELD` nicht explizit in ihrer `settings.py` gesetzt haben, erhalten bei der Migration eine entsprechende Warnung. **Asynchrone Paginierung.** Die neuen Klassen `AsyncPaginator` und `AsyncPage` bringen native Async-Unterstützung in die Paginierungslogik. In vollständig asynchronen View-Stacks entfällt damit die synchrone Blockierung bei der Seitenberechnung, was die Gesamtperformance bei datenintensiven Listenansichten verbessert. **Automatische Imports in der Shell.** Der Befehl `manage.py shell` importiert nun automatisch alle Modelle des Projekts sowie gängige Django-Hilfsmittel wie `django.utils.timezone` und `datetime`. Dieser Komfortgewinn beschleunigt das explorative Arbeiten und Debugging erheblich, da wiederholtes manuelles Importieren bei jeder neuen Shell-Sitzung entfällt. **Modernisierte E-Mail-API.** Djangos E-Mail-Klassen setzen nun auf Pythons `email.message.EmailMessage` anstelle der veralteten MIME-Klassen. Diese Umstellung bringt die E-Mail-Infrastruktur auf den aktuellen Stand der Python-Standardbibliothek und verbessert die Kompatibilität mit modernen E-Mail-Protokollen. ## Django-Interviewfragen für 2026 Technische Vorstellungsgespräche im Jahr 2026 greifen zunehmend die neueren Django-Features auf, neben den klassischen Themen wie ORM-Optimierung, Middleware-Architektur und REST-Framework-Grundlagen. Die folgenden Fragestellungen treten besonders häufig auf und prüfen sowohl theoretisches Verständnis als auch praktische Erfahrung mit den aktuellen Framework-Versionen. **Welches Problem lösen Composite Primary Keys, und welche Einschränkungen bestehen aktuell?** Diese Frage prüft das Verständnis für Datenbankdesign und die praktischen Grenzen der Implementierung. Eine fundierte Antwort benennt die Vorteile bei Verknüpfungstabellen: der Wegfall künstlicher Surrogatschlüssel, datenbankgestützte Eindeutigkeitsgarantie und geringerer Speicherverbrauch. Gleichzeitig müssen die drei zentralen Einschränkungen benannt werden: `ForeignKey` kann nicht auf Composite-Key-Modelle verweisen (stattdessen `ForeignObject`), die Django-Admin-Oberfläche bietet keine vollständige Unterstützung, und die nachträgliche Migration bestehender Tabellen erfordert manuelles SQL. **Worin unterscheidet sich das Background-Tasks-Framework von Django 6.0 von Celery?** Das integrierte Framework deckt einfache Fire-and-Forget-Aufgaben ab und benötigt in der Entwicklungsumgebung keinen externen Message Broker. Celery bietet hingegen Task-Chaining, periodische Ausführung über Celery Beat, Rate Limiting, Result Backends und eine ausgereifte Monitoring-Infrastruktur über Flower. Die Antwort sollte verdeutlichen, dass beide Lösungen unterschiedliche Komplexitätsstufen adressieren und in vielen Projekten parallel eingesetzt werden können. **Wie funktioniert die Middleware-Ausführungsreihenfolge in Django, und wo wird die CSP-Middleware eingeordnet?** Django verarbeitet Middleware in der definierten Reihenfolge bei eingehenden Requests und in umgekehrter Reihenfolge bei ausgehenden Responses. Die CSP-Middleware muss nach der `SecurityMiddleware` platziert werden, da sie HTTP-Response-Header modifiziert. Kandidaten sollten den Unterschied zwischen dem Enforcement-Modus und dem Report-Only-Modus erläutern und erklären können, wie der Nonce-Mechanismus inline Script-Tags absichert. **Was sind Template Partials und wann sollten sie anstelle von `{% include %}` eingesetzt werden?** Template Partials gruppieren mehrere Darstellungsvarianten eines Konzepts in einer einzigen Datei. Der Einsatz bietet sich insbesondere dann an, wenn mehrere zusammengehörige Fragmente existieren, die einzeln referenziert werden müssen -- etwa Karten- und Tabellenansichten desselben Datenobjekts. Klassisches `{% include %}` bleibt sinnvoll für einzelne, eigenständige Fragmente ohne logische Gruppierung. Partials reduzieren zudem die Dateiproliferation in größeren Projekten, bei denen Template-Verzeichnisse mit Dutzenden kleiner Include-Dateien schnell unübersichtlich werden. > **Migration von Django 5.2 auf 6.0** > > Django 6.0 beendet die Unterstützung für Python 3.10 und 3.11. Der Standard für `DEFAULT_AUTO_FIELD` wechselt zu `BigAutoField`. Die E-Mail-Klassen verwenden nun Pythons moderne `email.message`-API, was Code brechen kann, der auf die veralteten MIME-Interna zugreift. Gründliche Tests in einer Staging-Umgebung vor der Aktualisierung von Produktionsanwendungen sind zwingend erforderlich. ## Fazit Die zentralen Neuerungen von Django 5.2 und 6.0 im Überblick: - **Composite Primary Keys** (`CompositePrimaryKey`) beseitigen künstliche Surrogatschlüssel auf Verknüpfungstabellen und ermöglichen natürliche Mehrspalten-Primärschlüssel direkt im ORM - Das integrierte **`@task` / `.enqueue()`-Framework** übernimmt einfache Hintergrundaufgaben ohne externe Celery-Abhängigkeit und vereinfacht die lokale Entwicklung - **Template Partials** (`{% partialdef %}` / `{% partial %}`) gruppieren zusammengehörige Template-Fragmente in einer einzigen Datei und verbessern die Projektstruktur spürbar - Die native **CSP-Middleware** (`ContentSecurityPolicyMiddleware`) ersetzt das Drittanbieter-Paket `django-csp` für die meisten Anwendungsfälle und bietet einen risikoarmen Report-Only-Modus - **BigAutoField** als neuer Standard, asynchrone Paginierung, automatische Shell-Imports und die modernisierte Python-E-Mail-API runden das Release ab - Für die **Interviewvorbereitung** sind die Einschränkungen zusammengesetzter Schlüssel, die Abwägung zwischen dem Tasks-Framework und Celery sowie die Middleware-Ausführungsreihenfolge besonders relevante Themenfelder --- Source: SharpSkill (https://sharpskill.dev), tech interview preparation for your real stack. HTML version of this page: https://sharpskill.dev/de/blog/django/django-6-composite-primary-keys-background-tasks-2026