đ§ Django Debug Toolbar â Guide Approfondi
Guide IDEOâLab pour maĂźtriser le dĂ©bogage et l'optimisation de vos applications.
Introduction & Concepts
Le "Pourquoi ?" : Profiling, optimisation, N+1.
Debug Dev N+1Installation & Configuration
Middleware, urls.py, et le piĂšge des INTERNAL_IPS.
settings.py INTERNAL_IPS PiĂšgesPanel SQL (Le N+1)
Lire les requĂȘtes, dĂ©tecter les doublons, N+1, EXPLAIN.
SQL N+1 PerformancePanel Templates
Voir les templates utilisés et le contexte (variables).
Templates ContextePanel Static & Headers
Finder utilisĂ©s, fichiers statiques, en-tĂȘtes HTTP.
Static HeadersPanel Cache
Monitorer les hits/miss, temps de réponse du cache.
Cache RedisPanel Signals
Voir quels signaux ont été émis et par qui.
Signals HooksConfiguration Avancée
Panneaux custom, 3rd-party, SHOW_TOOLBAR_CALLBACK.
Avancé CallbackQu'est-ce que la Django Debug Toolbar (DjDT) ?
La **Django Debug Toolbar** est un ensemble de panneaux qui s'affichent sur le cĂŽtĂ© de votre page (en mode DEBUG=True) et vous donnent une **quantitĂ© incroyable d'informations** sur la requĂȘte en cours.
C'est l'outil de débogage et de profilage n°1 pour tout développeur Django. Il est non-intrusif et s'intÚgre parfaitement à votre flux de travail.
Quel problÚme cela résout-il ?
Quand votre page est lente, la cause est presque toujours la mĂȘme : **la base de donnĂ©es**. Mais comment savoir ?
- Combien de requĂȘtes SQL votre page a-t-elle exĂ©cutĂ©es ? 5 ? 10 ? 500 ?
- Quelle requĂȘte spĂ©cifique est lente ?
- Avez-vous un problÚme de **"N+1 queries"** (le "tueur de performance" n°1 de Django) ?
- Quels templates ont été utilisés pour rendre la page ?
- Quelles sont les variables de contexte passées à votre template ?
- Le cache est-il utilisé correctement ?
Sans la DjDT, répondre à ces questions est presque impossible. Avec elle, c'est **immédiat**.
Les Panneaux Essentiels
La barre d'outils est composée de "Panneaux". Voici les plus importants :
1. SQL
Le plus important. Il liste **chaque requĂȘte SQL** exĂ©cutĂ©e pour la page, leur durĂ©e, et le code Python qui l'a dĂ©clenchĂ©e. C'est ici que vous repĂ©rez les **N+1 queries** (par exemple, 100 requĂȘtes identiques dans une boucle).
2. Templates
Liste les templates et les "context processors" utilisés. Vous pouvez inspecter **toutes les variables** disponibles dans votre template (ex: AnonymousUser, ) pour voir exactement ce qu'elles contiennent.
3. Static Files
Montre comment Django a trouvé vos fichiers statiques (CSS, JS) et quel "finder" a été utilisé. TrÚs utile pour déboguer des problÚmes de collectstatic.
4. Cache
Affiche toutes les opérations de cache (set, get, delete), si c'est un "hit" (trouvé) ou un "miss" (non trouvé), et le temps de réponse. Indispensable si vous utilisez Redis ou Memcached.
Quand l'utiliser ?
TOUJOURS en environnement de **développement** (DEBUG = True).
C'est le premier package que vous devriez installer aprĂšs django lui-mĂȘme.
NE JAMAIS l'utiliser en Production
La DjDT ne doit **JAMAIS** ĂȘtre activĂ©e en production (DEBUG = False).
- Faille de sĂ©curitĂ© massive : Elle expose toute votre configuration, votre code source et vos requĂȘtes SQL Ă n'importe quel visiteur.
- Consommation de ressources : Elle ajoute une surcharge significative Ă chaque requĂȘte pour collecter les informations de dĂ©bogage.
La configuration correcte (expliquée dans l'onglet suivant) garantit qu'elle ne s'exécute que lorsque DEBUG est à True et pour des IPs spécifiques.
Alternatives & Compléments
1. Django-Silk
- Approche : Un outil de **profilage** pour les APIs (DRF). Il ne s'affiche pas sur la page, mais fournit une interface d'administration pour inspecter les requĂȘtes API, leur temps de rĂ©ponse, et les requĂȘtes SQL associĂ©es.
- Complément : DjDT est pour les pages rendues par Django (HTML). Silk est pour les endpoints d'API (JSON).
2. Sentry (Monitoring de Production)
- Approche : Service de monitoring d'erreurs et de performance pour la **production**.
- ComplĂ©ment : DjDT vous aide Ă trouver les problĂšmes en *dĂ©veloppement*. Sentry vous alerte des problĂšmes et des goulots d'Ă©tranglement qui surviennent en *production* (ex: "cette requĂȘte SQL est soudainement lente pour les utilisateurs rĂ©els").
3. Logging Django natif
- Approche : Configurer le module
loggingde Python pour Ă©crire les requĂȘtes SQL dans la console ou un fichier.
'loggers': {
'django.db.backends': {
'level': 'DEBUG',
'handlers': ['console'],
},
}Installation en 4 étapes
Suivez ces 4 étapes pour une installation standard (non-Docker).
1. Installer le package
pip install django-debug-toolbar
2. Ajouter Ă INSTALLED_APPS
Doit ĂȘtre ajoutĂ© Ă settings.py. L'ordre n'est pas critique, mais mettez-le avec les apps tierces.
# settings.py
INSTALLED_APPS = [
# ... autres apps
"debug_toolbar",
# ... vos apps
]3. Ajouter Ă MIDDLEWARE
L'ordre est important. Mettez-le le plus haut possible, mais **aprĂšs** les middlewares qui encodent le contenu (comme `GzipMiddleware`).
# settings.py
MIDDLEWARE = [
"django.middleware.security.SecurityMiddleware",
# "whitenoise.middleware.WhiteNoiseMiddleware",
"django.contrib.sessions.middleware.SessionMiddleware",
"debug_toolbar.middleware.DebugToolbarMiddleware", # <--- ICI
"django.middleware.common.CommonMiddleware",
"django.middleware.csrf.CsrfViewMiddleware",
# ... reste du middleware
]4. Ajouter les URLs
La barre d'outils a besoin de ses propres URLs pour charger ses assets. Ajoutez-les au urls.py **principal** de votre projet.
# ideolab_site/urls.py
from django.urls import path, include
from django.conf import settings # Important
urlpatterns = [
path('admin/', admin.site.urls),
# ... vos urls
]
if settings.DEBUG:
urlpatterns += [
path("__debug__/", include("debug_toolbar.urls")),
]
Note: Nous mettons cela dans le if settings.DEBUG: pour ĂȘtre sĂ»rs qu'il ne soit jamais exposĂ© en production.
Le PiÚge n°1 : La barre ne s'affiche pas !
Vous avez tout installé, DEBUG=True, mais la barre n'apparaßt pas. Pourquoi ?
Par sécurité, DjDT ne s'affiche que pour les adresses IP listées dans INTERNAL_IPS. Par défaut, cette liste est vide.
Solution : Ajouter 127.0.0.1
Ajoutez ceci Ă votre settings.py (ou settings/dev.py) :
# settings.py
INTERNAL_IPS = [
"127.0.0.1",
]127.0.0.1 est l'adresse de "localhost". Si vous développez localement, cela résoudra 99% des problÚmes d'affichage.
Configuration pour Docker / VM / WSL2
Si votre serveur Django tourne dans un conteneur Docker (ou une VM, ou WSL2) et que vous y accédez depuis votre machine hÎte, 127.0.0.1 ne fonctionnera pas.
Le serveur verra l'adresse IP de votre "vraie" machine (ex: 172.17.0.1). Le plus simple est d'utiliser une astuce qui dĂ©tecte l'IP de la requĂȘte.
Configuration Dynamique (Recommandée pour Docker)
Utilisez ce snippet dans settings.py. Il autorise dynamiquement l'IP du client si DEBUG=True.
# settings.py
if DEBUG:
import socket # only if DEBUG
# RécupÚre l'IP interne de la machine hÎte Docker
hostname, _, ips = socket.gethostbyname_ex(socket.gethostname())
INTERNAL_IPS = [ip[: ip.rfind(".")] + ".1" for ip in ips] + [
"127.0.0.1",
"10.0.2.2", # Pour Vagrant/VM
]
Alternative : SHOW_TOOLBAR_CALLBACK
Si la détection d'IP est trop compliquée, vous pouvez forcer l'affichage (EN DEV UNIQUEMENT) en ajoutant ceci à settings.py :
# settings.py
DEBUG_TOOLBAR_CONFIG = {
"SHOW_TOOLBAR_CALLBACK": lambda request: True,
}Cela désactive la vérification d'IP et affiche la barre pour tout le monde (tant que DEBUG=True).
Vérification
Pour vérifier que tout fonctionne :
- Lancez
python manage.py runserver. - Ouvrez votre navigateur sur
http://127.0.0.1:8000/. - Vous devriez voir un petit onglet "DjDT" sur le cÎté droit de votre page.
- Si vous utilisez l'admin Django, allez sur
/admin/, la barre doit aussi y apparaĂźtre.
La barre n'apparaĂźt toujours pas ?
- Vérifiez que
DEBUG = True. - Vérifiez que vous avez bien ajouté
"127.0.0.1"ĂINTERNAL_IPS. - VĂ©rifiez que votre
HTML est bien présent dans votre template (la barre s'injecte avant). - Videz le cache de votre navigateur.
Lire le Panel SQL
[...Contenu dĂ©taillĂ© : nombre de requĂȘtes, temps total, requĂȘtes dupliquĂ©es. Montrer la stack trace pour trouver la ligne de code Python...]
Cas Pratique : Le ProblĂšme N+1
[...Contenu dĂ©taillĂ© : Qu'est-ce qu'un N+1 ? 1 requĂȘte pour la liste (N articles) + N requĂȘtes pour les auteurs (1 par article)...]
[...Exemple de vue et template qui causent un N+1...]
# views.py
articles = Article.objects.all()
# template.html
{% for article in articles %}
par
{% endfor %}[...Montrer une capture d'Ă©cran de la DjDT affichant 101 requĂȘtes...]
Correction (ForeignKey) : select_related
[...Contenu détaillé : Utiliser `select_related` pour les relations ForeignKey (OneToOne, ForeignKey). Il fait un JOIN SQL...]
[...Exemple corrigé...]
# views.py
articles = Article.objects.select_related('author').all()[...Montrer une capture de la DjDT avec 1 seule requĂȘte...]
Correction (M2M) : prefetch_related
[...Contenu dĂ©taillĂ© : Utiliser `prefetch_related` pour les relations ManyToMany. Il fait 2 requĂȘtes (pas de JOIN) mais est plus efficace...]
[...Exemple avec des Tags M2M...]
articles = Article.objects.prefetch_related('tags').all()Analyser une requĂȘte avec EXPLAIN
[...Contenu détaillé : Cliquer sur le bouton "EXPLAIN" pour voir le plan d'exécution de la BDD et vérifier si les index sont utilisés...]
Templates utilisés
[...Contenu détaillé : Voir la hiérarchie (`base.html`, `page.html`) et le temps de rendu de chaque bloc...]
Contexte (Variables)
[...Contenu détaillé : Le "débogueur" n°1. Inspecter le contenu exact de ``, `AnonymousUser`, `` etc., tel que vu par le template...]
Context Processors
[...Contenu détaillé : Voir quelles variables globales sont ajoutées par les processors (ex: `request`, `perms`)...]
Panel Static Files
[...Contenu détaillé : Utile pour déboguer `collectstatic`. Voir les "finders" utilisés (`FileSystemFinder`, `AppDirectoriesFinder`) et le chemin exact du fichier trouvé...]
Panel Headers
[...Contenu dĂ©taillĂ© : Inspecter les en-tĂȘtes de RequĂȘte et de RĂ©ponse. Utile pour vĂ©rifier les cookies, CSRF token, Content-Type...]
Pourquoi l'utiliser ?
[...Contenu détaillé : Indispensable si vous utilisez `django.core.cache` (avec Redis/Memcached). Permet de vérifier si votre stratégie de cache fonctionne...]
Lire le Panel
[...Contenu détaillé : Voir les `cache.get`, `cache.set`, les "hits" (succÚs) et "misses" (échecs), et le temps pris par chaque opération de cache...]
Utilité
[...Contenu détaillé : Les signaux (Signals) sont des "hooks" qui se déclenchent à certains événements (ex: `pre_save`, `post_save`, `user_logged_in`). Ce panel vous montre lesquels sont déclenchés...]
Lire le Panel
[...Contenu détaillé : Voir le signal émis, les arguments (`sender`, `instance`), et les "receivers" (fonctions) qui ont été appelés...]
Gérer les panneaux
[...Contenu détaillé : Comment désactiver des panneaux (ex: Signals) ou réorganiser l'ordre via `DEBUG_TOOLBAR_PANELS` dans `settings.py`...]
Panneaux Tiers
[...Contenu dĂ©taillĂ© : Ajouter des panneaux utiles comme `ddt-request-history` (historique des requĂȘtes) ou `django-debug-toolbar-template-profiler` (profilage des templates)...]
DEBUG_TOOLBAR_CONFIG
[...Contenu détaillé : Autres options utiles comme `SHOW_TOOLBAR_CALLBACK` (déjà vu), `RESULTS_CACHE_SIZE`, `MAX_SQL_QUERIES`...]
