# Django 6.0 en 2026 : clés primaires composites, tâches en arrière-plan et questions d'entretien > Django 6.0 en 2026 : clés primaires composites, tâches en arrière-plan natives, template partials, middleware CSP et questions d'entretien technique. - Published: 2026-06-09 - Updated: 2026-06-09 - Author: SharpSkill - Tags: django, python, composite-primary-keys, background-tasks, csp - Reading time: 10 min --- Django 6.0 marque un tournant dans la maturité du framework en 2026. Cette version majeure apporte des fonctionnalités attendues depuis des années par la communauté Python : les clés primaires composites natives dans l'ORM, un système intégré de tâches en arrière-plan, les template partials pour les composants réutilisables et un middleware Content Security Policy directement dans le noyau. Chacune de ces évolutions réduit la dépendance aux paquets tiers et simplifie l'architecture des applications Django en production. > **Historique des versions Django** > > Django suit un cycle de release prévisible avec une version majeure tous les 8 mois environ. Django 5.2 LTS (avril 2025) a introduit les clés primaires composites en version stable. Django 6.0 (décembre 2025) les intègre pleinement au reste de l'ORM tout en ajoutant le système de tâches, les template partials et le middleware CSP. Python 3.12 ou supérieur est requis. ## Clés primaires composites avec CompositePrimaryKey Les bases de données relationnelles utilisent les clés primaires composites pour identifier un enregistrement de manière unique à partir de la combinaison de deux colonnes ou plus. Jusqu'à Django 5.2, modéliser cette relation nécessitait des solutions de contournement comme `unique_together` ou des paquets tiers. `CompositePrimaryKey` résout ce problème directement dans l'ORM. Le cas d'usage le plus courant concerne une table intermédiaire où la combinaison de deux clés étrangères constitue l'identité unique de l'enregistrement. L'exemple suivant modélise un inventaire où chaque produit dans chaque entrepôt possède une quantité associée : ```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) ``` Le champ `pk` reçoit les noms des colonnes sous-jacentes (et non les noms des champs du modèle). Django génère une contrainte `PRIMARY KEY (product_id, warehouse_id)` au niveau de la base de données, garantissant l'unicité sans nécessité d'un champ `id` auto-incrémenté. ## Interroger les clés composites dans l'ORM L'interaction avec l'ORM conserve l'interface habituelle. La clé composite est représentée sous forme de tuple Python, ce qui permet de filtrer, créer et assigner des enregistrements de manière directe : ```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" ``` Cette fonctionnalité s'avère particulièrement précieuse pour les équipes travaillant avec des schémas de base de données existants ou migrant depuis d'autres ORM qui supportaient déjà les clés composites. Django Admin, les sérialiseurs de DRF et le système de migrations reconnaissent automatiquement les modèles utilisant `CompositePrimaryKey`. ## Tâches en arrière-plan natives avec le décorateur @task Django 6.0 intègre un système de tâches en arrière-plan directement dans le framework. Le module `django.tasks` expose un décorateur `@task` et une méthode `.enqueue()` permettant de différer l'exécution de fonctions sans configurer de broker de messages externe ni de worker indépendant. Ce système cible les opérations courantes qui ne doivent pas bloquer le cycle requête-réponse HTTP : envoi de courriels, génération de rapports, traitement de fichiers et appels à des API externes. La définition des tâches suit la convention Django classique d'un module `tasks.py` dans chaque application : ```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 ``` Le dispatch depuis une vue s'effectue via la méthode `.enqueue()`, qui sérialise les arguments et les transmet au backend configuré pour une exécution asynchrone : ```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"}) ``` Django 6.0 fournit un backend base de données par défaut ainsi qu'un backend Redis pour les scénarios à volume plus élevé. La configuration dans `settings.py` permet de sélectionner le backend et d'ajuster les paramètres tels que le nombre de workers et l'intervalle de polling. Il convient de distinguer clairement le périmètre de ce système. Les tâches natives de Django 6.0 couvrent les cas d'usage simples à modérés de manière efficace. Pour les scénarios nécessitant un routage avancé de files, des workflows complexes (chains, chords), des politiques de relance avec backoff exponentiel configurable ou un traitement distribué sur plusieurs machines, [Celery](/fr/blog/django/django-celery-async-tasks-interview-2026) reste l'outil adapté. ## Template partials : composants réutilisables dans le moteur de templates Le moteur de templates de Django gagne une fonctionnalité que les développeurs de frameworks frontend considèrent comme acquise : la possibilité de définir des fragments réutilisables au sein d'un même fichier et de les référencer de manière sélective. Les balises `{% partialdef %}` et `{% partial %}` permettent de regrouper plusieurs composants visuels dans un seul template et de ne consommer que le fragment nécessaire. L'exemple suivant définit deux représentations d'un produit -- une carte pour les vues catalogue et une ligne pour les tableaux d'inventaire -- dans le même fichier de templates : ```html {% partialdef product_card %}
{{ product.price|floatformat:2 }} EUR
{% if product.in_stock %}In Stock{% else %}Sold Out{% endif %}