Quand j'ai lancé PartirDeZero.com, j'ai vite déchanté. J'avais passé des semaines à coder la plateforme, les cours vidéos et le système de progression. Mais une fois en ligne... le désert.
En vérifiant sur Google, j'ai réalisé que le moteur de recherche ne voyait que ma page d'accueil. Mes pages de cours, mes tutoriels, tout le contenu profond était invisible.
Le problème ? Contrairement à un CMS comme WordPress, Django ne génère pas de plan de site (sitemap.xml) par défaut. Il faut lui expliquer comment naviguer dans votre base de données.
Heureusement, le framework possède un module intégré puissant : django.contrib.sitemaps. Voici comment je l'ai mis en place en 3 étapes pour régler le problème en moins de 24h.
Étape 1 : La configuration (Le piège classique)
Avant de coder, il faut activer les bons modules. Beaucoup de tutos oublient de mentionner qu'il faut aussi le framework sites.
Dans votre fichier settings.py :
python
INSTALLED_APPS = [
# ...
'django.contrib.sites', # Indispensable
'django.contrib.sitemaps', # Le module magique
]
SITE_ID = 1 # Nécessaire pour que le framework 'sites' fonctionne
Étape 2 : La logique du Sitemap
C'est ici que ça devient intéressant. J'ai créé un fichier sitemaps.py (je préfère le mettre dans mon dossier de configuration principal, mais vous pouvez le mettre dans vos apps).
L'idée est de créer une classe par type de contenu. L'astuce consiste à utiliser reverse() pour les pages statiques (Contact, Accueil) et la méthode getabsoluteurl() pour vos modèles dynamiques (Articles, Cours).
Voici mon code actuel :
python
from django.contrib import sitemaps
from django.urls import reverse
# Importez vos modèles
from courses.models import Course
from blog.models import Post
# --- 1. SITEMAP DES COURS (DYNAMIQUE) ---
class CourseSitemap(sitemaps.Sitemap):
changefreq = "weekly" # Indique à Google la fréquence de mise à jour
priority = 0.9 # L'importance de la page (de 0.0 à 1.0)
def items(self):
# On ne veut indexer que les cours activés
return Course.objects.filter(enable=True)
def location(self, item):
# Django va chercher l'URL de chaque cours
return item.get_absolute_url()
# --- 2. SITEMAP DU BLOG (DYNAMIQUE) ---
class BlogSitemap(sitemaps.Sitemap):
changefreq = "weekly"
priority = 0.8
def items(self):
# On retourne tous les articles publiés
return Post.objects.filter(is_active=True)
def location(self, item):
return item.get_absolute_url()
# --- 3. PAGES STATIQUES ---
class StaticViewSitemap(sitemaps.Sitemap):
priority = 0.5
changefreq = "monthly"
def items(self):
# Ici, on met le 'name' de vos URLs dans urls.py
return ["home", "about", "contact"]
def location(self, item):
return reverse(item)
Étape 3 : Le Routing (URLs)
Enfin, il faut rendre ce fichier XML accessible. Dans votre fichier urls.py principal, on connecte les wagons.
Depuis Django 5, la syntaxe a légèrement changé (plus besoin de passer les vues en string), voici la version moderne :
python
from django.contrib.sitemaps.views import sitemap
from .sitemaps import CourseSitemap, BlogSitemap, StaticViewSitemap
# On regroupe tout dans un dictionnaire
sitemaps_dict = {
'cours': CourseSitemap,
'blog': BlogSitemap,
'static': StaticViewSitemap,
}
urlpatterns = [
# ... vos autres URLs ...
path(
'sitemap.xml',
sitemap,
{'sitemaps': sitemaps_dict},
name='django.contrib.sitemaps.views.sitemap'
),
]
Bonus : Ne pas oublier le portier (Robots.txt)
Avoir un plan, c'est bien. Dire à Google où il se trouve, c'est mieux. J'ai ajouté une ligne à la fin de mon fichier
robots.txt pour lui indiquer le chemin :
User-agent: *
Allow: /
Sitemap: [https://partirdezero.com/sitemap.xml](https://partirdezero.com/sitemap.xml)
Résultat
Une fois ce code poussé en production, je suis allé sur la Google Search Console pour soumettre mon nouveau sitemap.
Résultat ? En moins de 24h, Google avait découvert et validé mes pages de cours. Si vous lancez un projet Django, ne négligez pas cette étape, c'est la différence entre un site "fantôme" et un site qui existe vraiment.