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.

Django 6.0 Composite Primary Keys und Background Tasks Übersicht

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
<!-- templates/components/cards.html -->
{% partialdef product_card %}
<div class="card">
    <h3>{{ product.name }}</h3>
    <p class="price">{{ product.price|floatformat:2 }} EUR</p>
    <span class="stock {% if product.in_stock %}available{% else %}sold-out{% endif %}">
        {% if product.in_stock %}In Stock{% else %}Sold Out{% endif %}
    </span>
</div>
{% endpartialdef %}

{% partialdef product_row %}
<tr>
    <td>{{ product.name }}</td>
    <td>{{ product.price|floatformat:2 }} EUR</td>
    <td>{{ product.quantity }}</td>
</tr>
{% endpartialdef %}
html
<!-- templates/shop/catalog.html -->
{% extends "base.html" %}

{% block content %}
<div class="product-grid">
    {% for product in products %}
        {% include "components/cards.html#product_card" %}
    {% endfor %}
</div>
{% 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.

Bereit für deine Django-Interviews?

Übe mit unseren interaktiven Simulatoren, Flashcards und technischen Tests.

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

Fang an zu üben!

Teste dein Wissen mit unseren Interview-Simulatoren und technischen Tests.

Tags

#django
#python
#composite-primary-keys
#background-tasks
#django-6

Teilen

Verwandte Artikel