Présentation
Tu veux créer une application web.
Il faut des utilisateurs.
Une base de données.
Des permissions.
Des formulaires.
Des sessions.
Un espace d’administration.
Des emails.
Des pages.
Des URLs.
Des protections contre quelques façons créatives de transformer Internet en incendie.
À ce stade, deux philosophies apparaissent.
La première consiste à choisir une petite bibliothèque puis à assembler progressivement chaque pièce.
La seconde dit :
« Ces problèmes reviennent dans presque toutes les applications. Pourquoi ne pas commencer avec une boîte déjà remplie ? »
Django appartient clairement à la deuxième école.
Un framework qui préfère fournir trop de choses que pas assez
Django est un framework web open source écrit en Python.
Il fournit directement une grande partie de l’infrastructure nécessaire à une application web classique :
ORM ;
migrations de base de données ;
routage des URLs ;
vues ;
templates ;
formulaires ;
authentification ;
utilisateurs, groupes et permissions ;
sessions ;
interface d’administration ;
internationalisation ;
gestion des fichiers statiques ;
email ;
middleware ;
cache ;
outils de test ;
sécurité ;
commandes d’administration.
Le site officiel résume cette philosophie par une expression devenue presque indissociable du projet :
« batteries included ».
L’objectif n’est pas de résoudre chaque problème possible.
Il consiste à éviter que chaque nouveau projet recommence par reconstruire les mêmes fondations.
Django ne te donne pas seulement les briques. Il te propose déjà une manière raisonnable de construire la maison.
Né dans une rédaction, pas dans un laboratoire abstrait
Django apparaît au début des années 2000 au sein du journal Lawrence Journal-World, aux États-Unis.
Des développeurs comme Adrian Holovaty et Simon Willison travaillent alors sur plusieurs sites d’actualité et doivent produire rapidement des applications web alimentées par beaucoup de données.
Les besoins reviennent.
Modèles.
Administration.
Publication.
URLs.
Formulaires.
Bases de données.
Plutôt que de résoudre les mêmes problèmes encore et encore, les outils internes commencent à former un framework cohérent.
Django est publié en open source en 2005.
Son nom rend hommage au guitariste Django Reinhardt.
L’histoire explique beaucoup de ses choix.
Django n’a pas été conçu comme une démonstration de minimalisme architectural.
Il a été construit pour une situation beaucoup plus concrète :
il faut livrer une application sérieuse, avec des données réelles, des personnes qui l’utilisent et une deadline qui n’a absolument aucune intention de négocier.
Ce contexte se retrouve encore dans la devise officielle :
« The web framework for perfectionists with deadlines. »
Un framework Python complet, pas un générateur de sites
Django ne crée pas automatiquement une application à ta place.
Il ne remplace pas HTML.
Il ne remplace pas CSS.
Il ne remplace pas JavaScript.
Il ne remplace pas PostgreSQL.
Et il ne transforme pas magiquement une idée en SaaS rentable avant le déjeuner.
Il fournit une structure côté serveur.
Une application Django reçoit des requêtes HTTP, exécute la logique Python nécessaire, dialogue éventuellement avec une base de données puis retourne une réponse :
HTML ;
JSON ;
fichier ;
redirection ;
stream ;
ou autre réponse HTTP.
Le frontend peut être rendu directement avec les templates Django.
Ou être complètement séparé avec React, Vue, Svelte ou une application mobile qui consomme une API.
Django peut donc être utilisé comme framework full-stack traditionnel.
Mais aussi comme backend.
MTV plutôt que MVC
Django est souvent rapproché du modèle MVC — Model View Controller.
Sa terminologie historique est légèrement différente.
On parle plutôt de :
Model : les données et leur représentation ;
Template : la présentation ;
View : la logique qui reçoit la requête et décide de la réponse.
Le rôle que d’autres frameworks appellent parfois « controller » est en partie réparti entre le routage des URLs et les vues Django.
On rencontre donc souvent le terme MTV — Model Template View.
Cette différence de vocabulaire est moins importante que l’idée qu’elle porte :
séparer suffisamment les responsabilités pour que l’application puisse grandir sans devenir immédiatement un unique fichier app.py de 9 000 lignes.
Un projet composé d’applications
Django distingue généralement le project des apps.
Le projet contient la configuration globale.
Les apps regroupent des fonctionnalités plus ciblées.
Par exemple :
monprojet/
├── accounts/
├── articles/
├── billing/
├── dashboard/
└── monprojet/
articles peut gérer le contenu.
accounts les utilisateurs.
billing les paiements.
dashboard les vues internes.
Cette structure favorise une organisation modulaire.
Une app Django bien conçue peut même être réutilisée dans plusieurs projets.
Cela ne signifie pas qu’il faille transformer chaque fonction en application indépendante.
Comme toujours, l’architecture devient étrange lorsqu’on la prend comme concours de découpage.
Mais le mécanisme fournit une frontière utile.
Django 6.1 aujourd’hui
Au 8 août 2026, la dernière version officielle est Django 6.1, publiée le 5 août 2026.
Elle prend officiellement en charge :
Python 3.12 ;
Python 3.13 ;
Python 3.14.
Django 6.1 poursuit notamment le travail récent autour des performances de l’ORM, de l’administration, de la Content Security Policy, des tâches, de l’email et de plusieurs composants internes.
Mais « dernière version » ne veut pas nécessairement dire « meilleure version pour chaque projet ».
La branche Django 5.2 est une version LTS — Long-Term Support.
Elle reçoit un support étendu jusqu’en avril 2028.
Django 6.1 est, lui, une release fonctionnelle plus récente dont le support étendu est prévu jusqu’en décembre 2027.
Pour un nouveau projet, la décision peut donc être :
6.1 pour les fonctions récentes
ou
5.2 LTS pour une fenêtre de maintenance plus longue.
En avril 2027, Django 6.2 doit à son tour devenir la prochaine branche LTS.
Fonctionnalités
L’ORM : écrire des données comme des objets Python
L’une des pièces centrales de Django est son ORM — Object-Relational Mapper.
On peut définir un modèle :
from django.db import models
class Article(models.Model):
title = models.CharField(max_length=200)
published = models.BooleanField(default=False)
created_at = models.DateTimeField(auto_now_add=True)
Django utilise ensuite cette définition pour travailler avec la base de données.
Créer :
Article.objects.create(
title="Comprendre Django",
published=True,
)
Rechercher :
articles = Article.objects.filter(published=True)
Trier :
articles = Article.objects.order_by("-created_at")
L’idée est de manipuler les données avec une API Python au lieu d’écrire directement du SQL pour chaque opération.
Cela accélère énormément le développement.
Mais l’ORM n’efface pas la base de données.
Sous les objets Python se trouvent toujours :
tables ;
index ;
jointures ;
contraintes ;
transactions ;
requêtes ;
plans d’exécution.
Le confort de l’ORM est immense.
Il devient encore meilleur lorsqu’on comprend ce qu’il produit.
Les migrations : faire évoluer le schéma avec le code
Un modèle change.
Un champ apparaît.
Un autre devient nullable.
Une relation est ajoutée.
Django peut générer une migration :
python manage.py makemigrations
Puis l’appliquer :
python manage.py migrate
Les migrations décrivent l’évolution du schéma de base de données.
Elles peuvent être versionnées avec Git.
Une équipe peut ainsi partager non seulement son code, mais aussi l’histoire structurelle de ses données.
Cela paraît presque banal aujourd’hui.
Jusqu’au moment où l’on imagine gérer manuellement les changements SQL de quinze développeurs sur plusieurs environnements.
Les migrations deviennent alors soudain très sympathiques.
L’administration : probablement la fonction qui vend Django en cinq minutes
On définit un modèle.
On l’enregistre dans l’admin.
Et Django peut générer une interface de gestion.
Liste.
Recherche.
Filtres.
Création.
Modification.
Suppression.
Relations.
Permissions.
Tout cela à partir des modèles.
from django.contrib import admin
from .models import Article
admin.site.register(Article)
L’administration peut ensuite être fortement personnalisée.
Colonnes.
Filtres.
Actions.
Formulaires.
Relations inline.
Recherche.
Permissions.
Templates.
C’est une fonction extraordinaire pour :
back-offices ;
CMS internes ;
catalogues ;
équipes éditoriales ;
outils métiers ;
bases de données administrables.
Mais il faut comprendre sa fonction.
Django Admin est une interface pour les personnes qui administrent les données. Ce n’est pas automatiquement le frontend que tes utilisateurs doivent voir.
Confondre les deux conduit rapidement à tenter de transformer une excellente interface interne en produit grand public avec suffisamment de CSS pour commencer à négocier directement avec le destin.
Authentification, utilisateurs et permissions
Django possède son propre système d’authentification.
Il fournit notamment :
utilisateurs ;
mots de passe ;
hashing ;
groupes ;
permissions ;
sessions ;
connexion ;
déconnexion ;
réinitialisation de mot de passe ;
backends d’authentification personnalisables.
Les modèles peuvent recevoir automatiquement les permissions classiques :
add
change
delete
view
On peut ensuite attribuer ces permissions à un utilisateur ou à un groupe.
Cela donne une base solide pour de nombreuses applications métiers.
Django peut également être étendu pour fonctionner avec des systèmes d’authentification externes ou des modèles utilisateur personnalisés.
Et un conseil revient régulièrement dans l’écosystème :
si le projet aura probablement besoin d’un utilisateur personnalisé, mieux vaut le définir tôt.
Changer de modèle utilisateur lorsque quinze applications et trois années de migrations le référencent est techniquement possible.
Comme déplacer une cuisine après avoir terminé l’immeuble.
Formulaires et validation
Les formulaires web ont cette capacité remarquable à sembler simples jusqu’au moment où l’on doit réellement gérer :
validation ;
messages d’erreur ;
types ;
valeurs obligatoires ;
fichiers ;
sécurité ;
redisplay des données ;
relations avec les modèles.
Django possède un système de Forms et ModelForms.
from django import forms
from .models import Article
class ArticleForm(forms.ModelForm):
class Meta:
model = Article
fields = ["title", "published"]
Un formulaire peut :
valider les entrées ;
convertir les types ;
produire des erreurs structurées ;
générer des champs HTML ;
se connecter directement à un modèle.
C’est moins spectaculaire qu’un nouveau framework JavaScript avec une homepage animée.
Mais extrêmement utile lorsqu’il faut construire le soixante-douzième formulaire d’une application métier.
Routage des URLs
Django possède un routeur explicite.
from django.urls import path
from . import views
urlpatterns = [
path("articles/", views.article_list, name="article-list"),
]
Une URL est associée à une vue.
Les patterns peuvent être regroupés par app.
Les routes peuvent être nommées.
Les templates et le code peuvent ensuite générer des URLs sans recopier des chemins en dur partout.
C’est une petite abstraction.
Mais elle évite beaucoup de liens cassés lorsque l’application évolue.
Vues fonctionnelles ou orientées objet
Une vue Django peut être une simple fonction :
def home(request):
return render(request, "home.html")
Ou une class-based view.
Django fournit de nombreuses vues génériques pour les opérations classiques :
liste ;
détail ;
création ;
modification ;
suppression ;
redirection ;
templates.
Les class-based views peuvent supprimer beaucoup de répétitions.
Elles peuvent aussi produire un moment particulier où l’on regarde cinq niveaux d’héritage pour comprendre pourquoi une méthode est appelée.
Les deux styles sont donc utiles.
La meilleure vue est généralement celle dont l’équipe peut encore comprendre le comportement six mois plus tard.
Templates : produire du HTML côté serveur
Django possède son propre moteur de templates.
{% for article in articles %}
<article>
<h2>{{ article.title }}</h2>
</article>
{% endfor %}
Il prend en charge :
variables ;
boucles ;
conditions ;
héritage ;
inclusions ;
filtres ;
tags personnalisés.
Depuis Django 6.0, le langage de templates dispose également de template partials intégrés pour définir et réutiliser plus facilement de petits fragments.
Cette évolution accompagne le retour d’intérêt pour des architectures serveur modernes où l’on combine Django avec HTMX, Alpine.js ou de petites couches JavaScript plutôt qu’avec une SPA complète.
Le vieux rendu serveur n’était peut-être pas mort.
Il faisait juste une longue sieste marketing.
Une interface d’administration qui suit les modèles
L’admin ne se contente pas d’afficher des tables.
Elle comprend les relations des modèles.
Foreign keys.
Many-to-many.
Permissions.
Filtres.
Recherche.
Actions.
Widgets.
Elle peut fournir en quelques minutes un outil interne qui aurait demandé plusieurs jours de développement spécifique.
C’est probablement l’une des manifestations les plus pures de la philosophie Django :
écrire une fois la structure du domaine, puis laisser plusieurs parties du framework l’exploiter.
Le modèle alimente l’ORM.
Les migrations.
Les formulaires.
L’admin.
Les permissions.
Cette cohérence réduit énormément la duplication.
Sécurité intégrée
Django possède depuis longtemps une réputation sérieuse sur la sécurité web.
Le framework fournit des protections contre plusieurs catégories courantes d’attaques, notamment :
injections SQL à travers l’ORM paramétré ;
Cross-Site Request Forgery — CSRF ;
Cross-Site Scripting — XSS dans le moteur de templates lorsque l’échappement est utilisé normalement ;
clickjacking ;
mots de passe stockés avec des algorithmes de hash adaptés ;
sessions sécurisées ;
headers et réglages HTTPS.
Django 6.0 a ajouté un support intégré de Content Security Policy — CSP.
Une application peut maintenant configurer des politiques CSP et leurs headers directement à travers le framework.
Cela ne signifie évidemment pas :
« Django est sécurisé, donc je peux arrêter de penser à la sécurité ».
Un développeur peut toujours :
désactiver CSRF ;
injecter du HTML marqué comme sûr ;
écrire du SQL brut incorrect ;
exposer une SECRET_KEY ;
laisser DEBUG = True en production ;
mal configurer HTTPS.
Le framework fournit des garde-fous.
Il ne peut pas empêcher quelqu’un de les démonter.
Middleware : intervenir dans le cycle requête-réponse
Le middleware permet d’insérer une couche autour du traitement des requêtes.
Il peut servir pour :
authentification ;
sessions ;
sécurité ;
compression ;
logs ;
headers ;
localisation ;
mesure de performances ;
logique spécifique au projet.
Une requête traverse plusieurs middleware avant d’arriver à la vue.
La réponse retraverse ensuite la chaîne.
C’est une architecture très pratique pour les comportements transversaux.
À condition de ne pas transformer le middleware en tiroir où l’on cache toute la logique dont on ne savait pas quoi faire ailleurs.
Sessions, messages et cookies
Django inclut une infrastructure de sessions.
Une application peut associer des données temporaires à un utilisateur entre plusieurs requêtes.
Le framework possède également un système de messages permettant, par exemple, d’afficher :
« Article créé »
« Paiement échoué »
« Profil mis à jour »
après une redirection.
Ce sont de petites fonctions.
Mais la philosophie « batteries included » se mesure précisément à ce genre de détails.
Une application réelle est constituée de centaines de petites nécessités peu spectaculaires.
Django essaie d’en avoir déjà résolu beaucoup.
Django fournit une abstraction pour envoyer des emails.
SMTP.
Backends de développement.
Backends personnalisés.
Messages HTML.
Pièces jointes.
Depuis Django 6.1, le système évolue vers une nouvelle configuration MAILERS capable de gérer plusieurs backends email.
On peut imaginer :
un backend transactionnel ;
un backend marketing ;
un backend particulier pour certaines notifications.
Encore une fonction que l’on pourrait développer soi-même.
Et encore une raison de ne pas forcément le faire.
Tâches en arrière-plan
Django 6.0 a introduit un Tasks framework.
Il fournit une abstraction pour :
définir une tâche ;
la valider ;
la placer dans une file ;
gérer son résultat.
Par exemple, un email ou un traitement de données peut quitter le cycle HTTP principal.
Mais il existe une nuance importante :
Django ne fournit pas lui-même le worker de production qui exécute ces tâches.
Les backends intégrés sont principalement destinés au développement et aux tests.
L’exécution réelle nécessite une infrastructure externe adaptée.
Le framework fournit donc désormais le contrat.
Pas toute l’usine.
Celery, Dramatiq ou d’autres systèmes peuvent encore conserver une place selon le projet.
Synchrone et asynchrone
Django est historiquement un framework synchrone basé sur WSGI.
Il possède désormais une prise en charge croissante d’ASGI et du code asynchrone.
Des vues peuvent être async.
Certaines opérations disposent de versions asynchrones.
L’écosystème continue de progresser dans cette direction.
Mais Django n’est pas devenu du jour au lendemain un framework entièrement async dans chaque couche.
Certaines parties restent synchrones.
Certaines bibliothèques tierces aussi.
Et appeler du code bloquant dans une vue async reste une excellente façon de créer une architecture très moderne qui attend très efficacement.
Plusieurs bases de données officiellement supportées
Django prend officiellement en charge :
PostgreSQL
MariaDB
MySQL
Oracle
SQLite
SQLite est particulièrement pratique pour commencer.
Elle ne nécessite pas de serveur séparé.
Pour une application importante, la documentation Django recommande généralement de développer avec le même moteur que celui prévu en production.
PostgreSQL constitue aujourd’hui un choix extrêmement fréquent dans l’écosystème Django.
Le framework possède d’ailleurs des fonctionnalités supplémentaires spécifiques à PostgreSQL à travers django.contrib.postgres.
Cache
Django possède une abstraction de cache.
Selon l’infrastructure, le cache peut stocker :
résultats coûteux ;
pages ;
fragments ;
sessions ;
données fréquemment consultées.
Il peut fonctionner avec plusieurs backends.
Une application peut ainsi commencer simplement puis introduire davantage de cache lorsque la charge le nécessite.
Ce qui est souvent préférable à construire dès le lundi matin une architecture de cache distribuée destinée aux douze utilisateurs attendus le vendredi.
Internationalisation et localisation
Django possède depuis longtemps des outils pour :
traduire les chaînes ;
gérer plusieurs langues ;
adapter les formats de dates ;
travailler avec les fuseaux horaires ;
générer des catalogues de traduction ;
détecter ou sélectionner une langue.
Pour un projet multilingue, cette infrastructure évite de transformer les traductions en collection artisanale de conditions dispersées dans les templates.
Commandes de gestion
Le fichier manage.py ouvre l’accès à de nombreuses commandes :
python manage.py runserver
python manage.py migrate
python manage.py createsuperuser
python manage.py collectstatic
python manage.py test
python manage.py check
Les projets peuvent aussi créer leurs propres commandes.
C’est extrêmement pratique pour :
imports ;
maintenance ;
migration de données ;
automatisation ;
tâches administratives ;
scripts internes.
Plutôt que créer vingt scripts isolés dont personne ne sait lequel doit encore être utilisé, on peut intégrer ces opérations dans l’environnement Django lui-même.
Cas d’usage
Construire une application métier riche en données
Utilisateurs.
Clients.
Commandes.
Documents.
Permissions.
Statuts.
Historique.
Administration.
Recherche.
Relations.
Django est particulièrement à l’aise lorsque le cœur de l’application ressemble à cela.
On définit les modèles.
On construit les règles métier.
L’ORM gère les données.
L’admin fournit rapidement un back-office.
L’authentification contrôle les accès.
Les formulaires gèrent les entrées.
Cette combinaison rend Django extrêmement efficace pour les applications de gestion.
Construire un CMS ou une plateforme éditoriale
L’histoire même de Django vient de la publication web.
Le framework reste donc naturel pour :
articles ;
catégories ;
auteurs ;
médias ;
traductions ;
permissions éditoriales ;
workflow de publication ;
SEO ;
back-office.
Django lui-même n’est pas un CMS prêt à l’emploi.
Mais il constitue une excellente fondation pour en construire un.
Des projets comme Wagtail montrent d’ailleurs jusqu’où cette architecture peut être poussée.
Créer un SaaS
Une application SaaS possède souvent :
comptes ;
équipes ;
permissions ;
abonnements ;
dashboards ;
emails ;
base de données ;
back-office ;
API ;
tâches en arrière-plan.
Django fournit déjà une grande partie de cette plomberie.
Il reste à construire ce qui différencie réellement le produit.
Ce qui, en théorie, était justement l’idée.
Construire rapidement un outil interne
Une entreprise doit gérer :
inventaire ;
projets ;
demandes ;
clients ;
documents ;
catalogues ;
validations.
L’application n’a pas forcément besoin d’un frontend spectaculaire.
Elle a besoin de fonctionner.
L’admin Django devient alors particulièrement redoutable.
Quelques modèles.
Quelques permissions.
Quelques personnalisations.
Et l’équipe possède déjà une interface interne exploitable.
Pas forcément celle qui remportera un prix de design.
Mais celle qui peut empêcher vingt personnes de continuer à piloter l’entreprise avec final_tableau_2026_v12_corrige.xlsx.
Créer une API
Django peut parfaitement servir de backend API.
Il peut retourner du JSON directement.
Mais Django core ne fournit pas, à lui seul, toute l’expérience d’un framework REST spécialisé.
Pour cela, l’écosystème utilise largement :
Django REST Framework
ou des solutions comme :
Django Ninja.
Django REST Framework ajoute notamment :
serializers ;
viewsets ;
permissions API ;
authentification ;
pagination ;
browsable API ;
outils REST.
Django devient alors la couche :
modèles ;
ORM ;
utilisateurs ;
business logic ;
admin ;
infrastructure.
Et DRF expose cette logique au frontend ou aux applications mobiles.
Backend d’une application frontend séparée
Une application React, Vue ou Svelte peut complètement ignorer les templates Django.
Le frontend demande :
/api/articles/
Django vérifie l’utilisateur.
Interroge PostgreSQL.
Applique les permissions.
Renvoie du JSON.
Dans ce scénario, Django joue un rôle de backend structuré.
Son admin peut continuer à servir l’équipe interne pendant que le public utilise une interface complètement différente.
C’est l’un de ses avantages les plus pratiques.
Le frontend et le back-office n’ont pas besoin d’être la même application visuelle.
Construire avec très peu de JavaScript
Django peut aussi suivre l’approche inverse.
Templates côté serveur.
Formulaires Django.
HTMX pour quelques interactions.
Alpine.js pour certains comportements locaux.
On peut ainsi créer des applications très interactives sans nécessairement construire une SPA complète.
Cette approche connaît un regain d’intérêt.
Elle peut réduire :
complexité du build frontend ;
duplication des validations ;
gestion d’état ;
API internes inutiles ;
nombre de dépendances.
Tout ne nécessite pas deux applications séparées qui communiquent en JSON pour afficher un bouton « Modifier ».
Construire un prototype qui doit pouvoir survivre
Il existe des frameworks excellents pour créer une démonstration en quelques minutes.
Le problème commence lorsque la démonstration devient le produit.
Django possède une qualité particulière :
on peut démarrer assez vite tout en conservant des fondations capables de supporter un projet beaucoup plus grand.
Modèles.
Migrations.
Tests.
Apps.
Permissions.
Settings.
Admin.
La structure existe déjà.
Le prototype peut évoluer sans exiger immédiatement une réécriture complète.
À condition, évidemment, que le prototype n’ait pas transformé views.py en journal intime de 7 000 lignes.
Avis PANACHES
Django possède une qualité devenue presque inhabituelle dans le développement moderne :
il assume avoir des opinions.
Une application possède des modèles.
Un système de settings.
Des apps.
Des migrations.
Des URLs.
Des templates.
Des conventions.
Un admin.
Django ne te regarde pas au premier lancement en disant :
« Voici une fonction HTTP. Bonne chance pour le reste. »
Il propose un cadre.
Sa vraie force est la cohérence entre les pièces
Pris séparément, presque chaque composant de Django possède une alternative.
ORM ?
SQLAlchemy.
Templates ?
Jinja.
Forms ?
D’autres bibliothèques existent.
Auth ?
Encore d’autres.
Admin ?
Packages spécialisés.
Routing ?
Facile à trouver.
La puissance de Django ne vient donc pas du fait qu’aucune autre technologie ne sache faire ces choses.
Elle vient du fait que toutes ces pièces ont été pensées pour fonctionner ensemble.
Le modèle nourrit les migrations.
L’ORM utilise les modèles.
Les ModelForms utilisent les modèles.
L’admin utilise les modèles.
Les permissions utilisent les modèles.
Cette continuité diminue énormément le nombre de décisions et de connexions manuelles.
Batteries included ou dépendances imposées ?
Tout dépend du regard.
Pour certains développeurs :
« génial, tout est là ».
Pour d’autres :
« pourquoi est-ce que tout est déjà là ? »
C’est exactement la frontière entre Django et les microframeworks.
Avec Flask, on choisit davantage de composants.
Avec FastAPI, on obtient une excellente base moderne pour construire des API, puis on assemble le reste selon ses besoins.
Avec Django, beaucoup de choix sont déjà faits.
Cette contrainte peut accélérer énormément un projet.
Elle peut aussi sembler excessive si l’application n’a besoin que de trois endpoints JSON.
Django vs FastAPI
La comparaison revient souvent.
Mais les deux outils ne partent pas exactement du même endroit.
FastAPI excelle dans la construction d’API modernes, notamment grâce aux annotations de types Python, à OpenAPI et à son orientation async.
Django vise un périmètre plus large :
données ;
auth ;
admin ;
templates ;
sessions ;
formulaires ;
migrations ;
applications métier complètes.
Si l’objectif est :
« je veux huit endpoints API extrêmement propres »
FastAPI peut être naturel.
Si l’objectif devient :
« utilisateurs, rôles, admin, trente modèles, formulaires, emails, CMS, back-office et une API »
Django commence à montrer pourquoi il transporte davantage de bagages.
Django vs Flask
Flask prend presque la philosophie opposée.
Un cœur petit.
Beaucoup de liberté.
Ajouter ce dont le projet a besoin.
Cela peut être excellent pour :
petits services ;
prototypes ;
applications particulières ;
équipes souhaitant choisir précisément chaque composant.
Django préfère fournir une architecture plus complète.
La question n’est donc pas :
« lequel est meilleur ? »
Mais :
« quelle quantité de décisions veut-on prendre nous-mêmes ? »
Django vs Laravel ou Ruby on Rails
Laravel et Ruby on Rails sont probablement plus proches philosophiquement de Django.
Frameworks full-stack.
ORM.
Migrations.
Conventions.
Écosystèmes importants.
Développement rapide.
Rails pousse historiquement très loin la convention over configuration.
Laravel bénéficie d’un écosystème PHP extrêmement large et d’une expérience développeur très travaillée.
Django possède de son côté l’avantage de vivre dans l’univers Python.
Et cet univers est devenu gigantesque.
Data.
Scripts.
IA.
Automatisation.
Traitement d’images.
Recherche.
Django peut donc se connecter naturellement à beaucoup de bibliothèques Python sans créer une deuxième stack technologique.
L’admin reste un super-pouvoir
Il est facile de sous-estimer Django Admin parce qu’il n’est pas très spectaculaire.
Puis arrive un projet avec quarante modèles.
Des personnes non techniques doivent modifier les données.
Il faut des permissions.
Des filtres.
Une recherche.
Des actions.
Des relations.
Et soudain l’équipe comprend qu’elle possédait depuis le premier jour un back-office largement fonctionnel.
C’est probablement l’une des fonctions qui produit le plus grand rapport :
lignes de code écrites / travail réellement évité.
Django n’est pas vieux. Il est mature.
Django existe depuis plus de vingt ans.
Dans la technologie, cela peut provoquer un réflexe étrange :
« Si ça existe depuis longtemps, il doit forcément exister quelque chose de plus moderne. »
Parfois oui.
Mais « récent » et « meilleur » ne sont pas synonymes.
Django possède :
des années de corrections ;
une documentation immense ;
des conventions stabilisées ;
un écosystème mature ;
des pratiques de sécurité solides ;
des migrations éprouvées ;
une communauté mondiale ;
des entreprises qui l’utilisent en production depuis longtemps.
La maturité produit moins de screenshots excitants qu’un nouveau framework sorti jeudi.
Elle produit souvent davantage de nuits tranquilles.
Mais Django doit continuer à évoluer
Le web de 2026 n’est plus celui de 2005.
Async.
APIs.
SPAs.
HTMX.
WebSockets.
Background tasks.
CSP.
Type hints.
IA.
Architectures distribuées.
Django a dû intégrer progressivement ces changements.
Les versions 6.0 et 6.1 montrent justement ce mouvement :
CSP intégrée ;
template partials ;
framework de tâches ;
améliorations async ;
évolution des emails ;
nouvelles optimisations ORM.
L’équilibre est délicat.
Bouger trop vite casserait un écosystème immense.
Bouger trop lentement transformerait Django en musée.
Pour l’instant, le projet continue plutôt bien à marcher sur cette ligne.
Django n’essaie pas d’être le plus petit framework. Il essaie de faire disparaître suffisamment de problèmes ordinaires pour que tu puisses consacrer ton temps aux problèmes particuliers de ton application.
Points d’attention
Django 6.1 n’est pas une LTS
Au 8 août 2026, Django 6.1 est la version officielle la plus récente.
Son support principal doit se terminer en avril 2027.
Son support étendu en décembre 2027.
La branche 5.2 LTS reste supportée jusqu’en avril 2028.
Cela crée deux stratégies parfaitement légitimes.
Projet voulant les fonctions récentes :
Django 6.1
Projet privilégiant une fenêtre de support longue et très stable :
Django 5.2 LTS
La prochaine LTS prévue est Django 6.2, annoncée pour avril 2027.
Une version plus récente n’est donc pas automatiquement un meilleur choix opérationnel.
Django 6.1 demande un Python récent
Django 6.1 prend officiellement en charge :
Python 3.12 ;
3.13 ;
3.14.
Un vieux projet encore sous Python 3.10 ou 3.11 ne peut donc pas simplement installer Django 6.1 et espérer que tout négocie gentiment.
Django 5.2 est la dernière série à conserver le support de Python 3.10 et 3.11.
Une montée de version Django peut ainsi impliquer une montée de version Python.
Puis une vérification des dépendances.
Puis des tests.
Puis, éventuellement, une tasse de café suffisamment grande.
L’ORM ne dispense pas de comprendre SQL
Écrire :
Article.objects.all()
est facile.
Écrire une requête ORM qui déclenche 4 000 requêtes SQL sans s’en rendre compte l’est malheureusement aussi.
Le problème classique du N+1 reste possible.
Django fournit :
select_related()
prefetch_related()
et, depuis Django 6.1, de nouveaux fetch modes capables d’améliorer certains scénarios de chargement à la demande.
Mais aucune abstraction ne supprime totalement la nécessité de comprendre :
jointures ;
index ;
cardinalité ;
transactions ;
coût des requêtes.
Un ORM rend SQL plus confortable.
Pas facultatif intellectuellement.
Les migrations peuvent entrer en conflit
Deux développeurs modifient le même modèle sur deux branches.
Chacun génère une migration.
Les branches fusionnent.
Django découvre maintenant deux futurs différents pour la même histoire.
Il faut parfois fusionner ou réorganiser les migrations.
Ce n’est pas une faiblesse spécifique à Django.
C’est la conséquence logique de vouloir versionner l’évolution d’une base de données dans un projet distribué.
Mais plus une application possède de développeurs et de migrations, plus cette discipline devient importante.
L’admin n’est pas une interface utilisateur universelle
Django Admin est conçu pour des utilisateurs de confiance qui gèrent des données.
Il peut être personnalisé.
Beaucoup.
Mais essayer de le transformer en frontend grand public possède rapidement des limites.
UX.
Navigation.
Design.
Workflows très spécifiques.
Mobile.
Interactions avancées.
L’admin est excellent quand il reste proche de son intention :
administrer les données du système.
Pour le produit final, construire des vues dédiées est généralement préférable.
runserver n’est pas un serveur de production
La commande :
python manage.py runserver
est fantastique pour développer.
Elle n’est pas destinée à servir une application en production.
Django doit alors être déployé à travers une infrastructure adaptée utilisant WSGI ou ASGI.
Par exemple :
Gunicorn ;
uWSGI ;
Uvicorn ;
Daphne ;
Hypercorn ;
selon l’architecture choisie.
Il faut également gérer :
reverse proxy ;
HTTPS ;
processus ;
logs ;
monitoring ;
statics ;
media ;
timeouts ;
redémarrages ;
sécurité.
Le bouton « deploy » n’est pas inclus dans le framework.
DEBUG = True ne doit jamais finir en production
En développement, DEBUG = True fournit des pages d’erreur extrêmement détaillées.
Tracebacks.
Variables.
Settings.
Informations sur le code.
C’est merveilleux quand on développe.
Et exactement le genre d’informations que l’on ne souhaite pas afficher à un inconnu sur Internet.
En production :
DEBUG = False
n’est pas une suggestion esthétique.
C’est une mesure de sécurité élémentaire.
La SECRET_KEY est réellement secrète
Django utilise SECRET_KEY pour plusieurs mécanismes cryptographiques de signature.
Elle ne doit pas être :
commitée publiquement ;
réutilisée partout ;
codée en dur dans un repository public ;
copiée depuis un tutoriel.
En production, elle doit venir d’une source sécurisée :
variable d’environnement ;
gestionnaire de secrets ;
configuration privée.
Django fournit même manage.py check --deploy pour signaler plusieurs configurations dangereuses.
Le framework essaie de prévenir.
Mais il ne peut pas arracher le fichier .env des mains du développeur avant le git add ..
Les fichiers statiques et médias demandent une vraie stratégie
CSS.
JavaScript.
Images de l’interface.
Uploads utilisateurs.
Ces éléments ne doivent pas être traités exactement comme le code Python.
Django possède :
STATIC_URL
STATIC_ROOT
MEDIA_URL
MEDIA_ROOT
et la commande :
python manage.py collectstatic
Mais en production, il faut décider où ces fichiers vivent réellement.
Nginx.
CDN.
S3 ou stockage compatible.
Volume persistant.
Service externe.
Les uploads utilisateurs sont particulièrement importants.
Le container de l’application peut être jetable.
Les photos des utilisateurs, beaucoup moins.
Le système de tâches ne fournit pas encore toute l’infrastructure
Django 6.0 a ajouté un framework de tâches.
C’est une évolution importante.
Mais Django ne fournit pas de worker de production intégré qui exécute ces tâches à lui seul.
Une infrastructure externe reste nécessaire.
Il ne faut donc pas lire :
« Django possède maintenant les tâches »
comme :
« Celery, Redis et les workers n’existent plus ».
Le nouveau framework standardise une partie de l’API.
L’exécution dépend toujours du backend et de l’architecture choisis.
Async ne signifie pas que tout Django est devenu async
Django supporte WSGI et ASGI.
Il possède des vues async et un nombre croissant d’API asynchrones.
Mais certaines parties du framework ou de l’écosystème restent synchrones.
Un projet doit donc comprendre où se trouvent les frontières.
Sinon, on peut créer une vue :
async def ma_vue(request):
...
puis appeler immédiatement trois bibliothèques bloquantes à l’intérieur.
Le mot async est bien présent.
Le bénéfice, légèrement moins.
Django REST Framework n’est pas Django
La confusion est fréquente.
Django REST Framework — DRF est un projet tiers construit au-dessus de Django.
Il possède sa propre version.
Sa propre documentation.
Son propre cycle de maintenance.
Django lui-même peut produire du JSON et construire une API.
Mais les serializers, viewsets et nombreuses fonctions REST couramment associées à Django viennent souvent de DRF.
Cette distinction compte lorsqu’on évalue les dépendances d’un projet.
Le frontend moderne peut ajouter une deuxième architecture complète
Django + React.
Django + Vue.
Django + Next.js.
C’est parfaitement valide.
Mais cela signifie parfois :
routing backend ;
routing frontend ;
validation backend ;
validation frontend ;
auth backend ;
état frontend ;
build Node ;
build Python ;
API ;
CORS ;
deux écosystèmes de dépendances.
Une SPA n’est donc pas automatiquement « plus moderne ».
Elle est surtout une architecture différente.
Pour certaines applications, elle est indispensable.
Pour d’autres, les templates Django accompagnés de HTMX ou d’un peu de JavaScript peuvent être beaucoup plus simples.
Les applications Django peuvent devenir des monolithes très confortables
Django facilite l’ajout de fonctionnalités.
Parfois trop bien.
On ajoute une app.
Puis une autre.
Puis un modèle.
Puis une logique dans signals.py.
Puis une fonction dans utils.py.
Puis un service.
Puis une méthode de modèle qui envoie un email et modifie trois autres tables parce que « c’était pratique ».
Dix ans plus tard, le monolithe fonctionne encore.
Personne n’ose le regarder directement.
Django ne crée pas ce problème.
Mais sa productivité peut permettre à un projet de devenir gros avant que l’équipe soit obligée de réfléchir sérieusement aux frontières architecturales.
Les signals sont puissants et faciles à rendre invisibles
Django possède un système de signals.
Un objet est sauvegardé.
Une fonction se déclenche ailleurs.
C’est pratique pour découpler certaines opérations.
Mais trop de signals peuvent transformer le flux du programme en chasse au trésor.
Tu sauvegardes un utilisateur.
Pourquoi trois emails sont-ils partis ?
Pourquoi une facture vient-elle d’être créée ?
Pourquoi le cache a-t-il changé ?
Ah.
post_save.
Dans une application métier importante, une logique explicite est souvent plus facile à suivre qu’une forêt d’effets secondaires invisibles.
Choisir SQLite au début peut masquer certains comportements
SQLite est parfaite pour :
apprendre ;
tester ;
prototyper ;
petits projets.
Elle est intégrée à Python et demande très peu de configuration.
Mais PostgreSQL, MySQL, MariaDB et Oracle n’ont pas exactement les mêmes comportements.
Types.
Contraintes.
Concurrence.
Fonctions SQL.
Transactions.
Si une application importante doit utiliser PostgreSQL en production, développer suffisamment tôt avec PostgreSQL réduit le risque de découvrir les différences la veille du déploiement.
La documentation Django recommande d’ailleurs cette cohérence pour les projets substantiels.
Une nouvelle version de Django mérite de lire les release notes
Django possède un système de dépréciation relativement discipliné.
Mais une montée de version peut tout de même apporter :
changements incompatibles ;
suppressions ;
nouvelles versions minimales de bases de données ;
évolution des dépendances ;
nouveaux comportements.
Django 6.1, par exemple, demande désormais au minimum :
PostgreSQL 15 ;
MySQL 8.4 ;
MariaDB 10.11 ;
SQLite 3.37.
Mettre à jour le framework sans regarder l’infrastructure située dessous peut donc produire quelques surprises.
Open source ne signifie pas « sans maintenance »
Django est gratuit.
BSD.
Open source.
Pas de licence commerciale par utilisateur.
Pas d’abonnement pour activer l’ORM premium.
Mais une application Django réelle possède toujours un coût.
Serveur.
Base de données.
Stockage.
Backups.
Emails.
CDN.
Monitoring.
Maintenance.
Mises à jour de sécurité.
Développement.
Le framework est gratuit.
L’application qui utilise le framework vit toujours dans le monde physique des factures et des machines.
Quand Django est-il trop gros ?
Si le projet est essentiellement :
trois endpoints ;
aucune base de données complexe ;
aucun back-office ;
aucun utilisateur ;
aucun formulaire ;
aucune session ;
aucune logique métier significative ;
alors Django peut effectivement sembler lourd.
FastAPI ou Flask peuvent être plus directs.
À l’inverse, si trois mois plus tard le petit service possède :
utilisateurs ;
permissions ;
emails ;
vingt modèles ;
admin ;
dashboard ;
back-office ;
paiements ;
alors la quantité de fonctionnalités de Django commence soudainement à ressembler moins à du poids qu’à du travail déjà fait.
C’est probablement la bonne manière de choisir.
Pas :
« Django est-il moderne ? »
Mais :
« combien des problèmes que Django résout vais-je réellement rencontrer ? »
Django vaut surtout la peine quand ton application a suffisamment de métier, de données et d’utilisateurs pour que reconstruire les fondations commence à devenir une distraction.