2 次代码提交 428a750b23 ... 0e33d284c7

作者 SHA1 备注 提交日期
  Laurent Hazart 0e33d284c7 Merge branch 'main' of https://dev.duhaz.fr/MrDuhaz/blog-duhaz-v3 2 周之前
  Laurent Hazart c13e157d29 Initial commit of SEO sitemap troubleshooting scripts and documentation. 2 周之前
共有 3 个文件被更改,包括 522 次插入0 次删除
  1. 257 0
      docs/seo/DEPANNAGE_SITEMAP_VIDE.md
  2. 175 0
      scripts/diagnose_sitemap.py
  3. 90 0
      scripts/fix_sitemap_sites.py

+ 257 - 0
docs/seo/DEPANNAGE_SITEMAP_VIDE.md

@@ -0,0 +1,257 @@
+# 🚨 DÉPANNAGE : Sitemap Vide
+
+## Problème
+Le sitemap à l'URL https://www.duhaz.fr/sitemap.xml est vide ou ne contient aucune URL.
+
+## 🔍 Causes possibles
+
+1. **django.contrib.sites non configuré** (cause la plus fréquente)
+2. Aucun article publié dans la base de données
+3. Migrations non appliquées
+4. Serveur non redémarré après les modifications
+
+## ✅ Solution rapide (automatique)
+
+### Étape 1 : Exécuter le script de correction
+
+```bash
+cd /Users/duhaz/projets/blog-duhaz
+source venv/bin/activate  # Si vous avez un venv
+python scripts/fix_sitemap_sites.py
+```
+
+Ce script va :
+- ✅ Créer ou mettre à jour la table `django_site`
+- ✅ Configurer le domaine `www.duhaz.fr`
+- ✅ Vérifier la configuration
+
+### Étape 2 : Redémarrer le serveur
+
+```bash
+# En développement
+python manage.py runserver
+
+# En production (selon votre config)
+systemctl restart gunicorn
+# ou
+supervisorctl restart duhaz_blog
+```
+
+### Étape 3 : Vérifier le sitemap
+
+Ouvrir dans le navigateur : https://www.duhaz.fr/sitemap.xml
+
+---
+
+## 🔧 Solution manuelle (si le script ne fonctionne pas)
+
+### 1. Appliquer les migrations
+
+```bash
+python manage.py migrate
+```
+
+### 2. Configurer django.contrib.sites
+
+```bash
+python manage.py shell
+```
+
+Dans le shell Python :
+
+```python
+from django.contrib.sites.models import Site
+
+# Créer ou mettre à jour le site
+try:
+    site = Site.objects.get(id=1)
+    site.domain = 'www.duhaz.fr'
+    site.name = 'Mr Duhaz'
+    site.save()
+    print("✅ Site mis à jour")
+except Site.DoesNotExist:
+    Site.objects.create(id=1, domain='www.duhaz.fr', name='Mr Duhaz')
+    print("✅ Site créé")
+
+# Vérifier
+print(Site.objects.all())
+
+exit()
+```
+
+### 3. Vérifier les articles
+
+```bash
+python manage.py shell
+```
+
+```python
+from blog.models import Blog
+
+# Compter les articles publiés
+count = Blog.objects.filter(b_publier=True).count()
+print(f"Articles publiés : {count}")
+
+# Afficher les premiers
+for blog in Blog.objects.filter(b_publier=True)[:5]:
+    print(f"- {blog.b_titre}")
+
+exit()
+```
+
+### 4. Redémarrer et tester
+
+```bash
+# Redémarrer le serveur
+systemctl restart gunicorn
+
+# Tester
+curl https://www.duhaz.fr/sitemap.xml
+```
+
+---
+
+## 🧪 Diagnostic complet
+
+Pour identifier précisément le problème :
+
+```bash
+python scripts/diagnose_sitemap.py
+```
+
+Ce script vérifie :
+- ✅ Configuration de django.contrib.sites
+- ✅ SITE_ID dans settings.py
+- ✅ Nombre d'articles publiés
+- ✅ Nombre de catégories
+- ✅ Génération du sitemap
+
+---
+
+## 📋 Checklist de vérification
+
+- [ ] `django.contrib.sites` dans INSTALLED_APPS
+- [ ] `django.contrib.sitemaps` dans INSTALLED_APPS
+- [ ] `SITE_ID = 1` dans settings.py
+- [ ] Migration `migrate` appliquée
+- [ ] Site créé dans la table `django_site`
+- [ ] Domaine = `www.duhaz.fr`
+- [ ] Au moins 1 article avec `b_publier=True`
+- [ ] Serveur redémarré
+- [ ] URL configurée dans `urls.py`
+
+---
+
+## 🔍 Vérifications manuelles
+
+### Vérifier la table django_site
+
+```sql
+-- Se connecter à la base de données
+python manage.py dbshell
+
+-- Vérifier la table
+SELECT * FROM django_site;
+
+-- Doit afficher :
+-- id | domain          | name
+-- 1  | www.duhaz.fr    | Mr Duhaz
+```
+
+### Vérifier l'URL du sitemap
+
+```bash
+python manage.py shell
+```
+
+```python
+from django.urls import reverse
+print(reverse('django.contrib.sitemaps.views.sitemap'))
+# Doit afficher : /sitemap.xml
+
+exit()
+```
+
+---
+
+## ⚠️ Erreurs courantes
+
+### Erreur : "table django_site doesn't exist"
+
+**Solution :**
+```bash
+python manage.py migrate
+```
+
+### Erreur : "SITE_ID not defined"
+
+**Solution :** Ajouter dans `duhaz_blog/settings.py` :
+```python
+SITE_ID = 1
+```
+
+### Sitemap vide mais pas d'erreur
+
+**Causes possibles :**
+1. Aucun article avec `b_publier=True`
+2. Domaine du site incorrect (pas `www.duhaz.fr`)
+3. Cache non vidé
+
+**Solutions :**
+```bash
+# Vider le cache
+python manage.py shell
+>>> from django.core.cache import cache
+>>> cache.clear()
+>>> exit()
+
+# Redémarrer
+systemctl restart gunicorn
+```
+
+---
+
+## 🎯 Test final
+
+Après correction, le sitemap doit contenir :
+
+```xml
+<?xml version="1.0" encoding="UTF-8"?>
+<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
+  <url>
+    <loc>https://www.duhaz.fr/blog/</loc>
+    <lastmod>2025-XX-XX</lastmod>
+    <changefreq>daily</changefreq>
+    <priority>0.5</priority>
+  </url>
+  <url>
+    <loc>https://www.duhaz.fr/blog/votre-article</loc>
+    ...
+  </url>
+  ...
+</urlset>
+```
+
+---
+
+## 📞 Support
+
+Si le problème persiste :
+
+1. Exécuter `python scripts/diagnose_sitemap.py`
+2. Consulter les logs Django
+3. Vérifier les permissions de la base de données
+4. S'assurer que le serveur a bien redémarré
+
+---
+
+## 📚 Scripts disponibles
+
+- `scripts/diagnose_sitemap.py` - Diagnostic complet
+- `scripts/fix_sitemap_sites.py` - Correction automatique
+- `scripts/generate_sitemap_preview.py` - Génération test
+
+---
+
+**La cause la plus fréquente est django.contrib.sites non configuré.**  
+**Exécutez `python scripts/fix_sitemap_sites.py` pour corriger automatiquement !**

+ 175 - 0
scripts/diagnose_sitemap.py

@@ -0,0 +1,175 @@
+#!/usr/bin/env python3
+"""
+Script de diagnostic du sitemap
+Identifie pourquoi le sitemap est vide
+"""
+
+import os
+import sys
+from pathlib import Path
+
+# Ajouter le répertoire parent au path
+sys.path.insert(0, str(Path(__file__).resolve().parent.parent))
+
+# Configuration Django
+os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'duhaz_blog.settings')
+import django
+django.setup()
+
+from blog.models import Blog, Cat_Blog
+from core.models import Page
+from django.contrib.sites.models import Site
+
+
+def diagnose_sitemap():
+    """Diagnostique les problèmes du sitemap"""
+    print("\n" + "="*70)
+    print("DIAGNOSTIC DU SITEMAP")
+    print("="*70 + "\n")
+    
+    issues = []
+    
+    # 1. Vérifier django.contrib.sites
+    print("1️⃣  Vérification de django.contrib.sites...")
+    try:
+        sites = Site.objects.all()
+        if sites.exists():
+            print(f"   ✅ {sites.count()} site(s) configuré(s)")
+            for site in sites:
+                print(f"      - ID: {site.id}, Domaine: {site.domain}, Nom: {site.name}")
+                if site.domain != 'www.duhaz.fr' and site.domain != 'duhaz.fr':
+                    issues.append(f"⚠️  Domaine du site incorrect : {site.domain}")
+        else:
+            issues.append("❌ Aucun site configuré dans django.contrib.sites")
+            print("   ❌ Aucun site configuré !")
+    except Exception as e:
+        issues.append(f"❌ Erreur avec django.contrib.sites : {e}")
+        print(f"   ❌ Erreur : {e}")
+    
+    # 2. Vérifier SITE_ID
+    print("\n2️⃣  Vérification de SITE_ID...")
+    from django.conf import settings
+    if hasattr(settings, 'SITE_ID'):
+        print(f"   ✅ SITE_ID = {settings.SITE_ID}")
+    else:
+        issues.append("❌ SITE_ID non défini dans settings.py")
+        print("   ❌ SITE_ID non défini !")
+    
+    # 3. Vérifier les articles de blog
+    print("\n3️⃣  Vérification des articles de blog...")
+    try:
+        blogs = Blog.objects.filter(b_publier=True)
+        print(f"   ✅ {blogs.count()} article(s) publié(s)")
+        if blogs.count() == 0:
+            issues.append("⚠️  Aucun article publié trouvé")
+        else:
+            # Afficher les 3 premiers
+            for blog in blogs[:3]:
+                print(f"      - {blog.b_titre}")
+    except Exception as e:
+        issues.append(f"❌ Erreur avec les articles : {e}")
+        print(f"   ❌ Erreur : {e}")
+    
+    # 4. Vérifier les catégories
+    print("\n4️⃣  Vérification des catégories...")
+    try:
+        cats = Cat_Blog.objects.all()
+        print(f"   ✅ {cats.count()} catégorie(s)")
+        if cats.count() == 0:
+            issues.append("⚠️  Aucune catégorie trouvée")
+    except Exception as e:
+        issues.append(f"❌ Erreur avec les catégories : {e}")
+        print(f"   ❌ Erreur : {e}")
+    
+    # 5. Vérifier les pages
+    print("\n5️⃣  Vérification des pages statiques...")
+    try:
+        pages = Page.objects.filter(p_publier=True, p_type='page')
+        print(f"   ✅ {pages.count()} page(s) publiée(s)")
+        if pages.count() == 0:
+            issues.append("⚠️  Aucune page statique trouvée")
+    except Exception as e:
+        issues.append(f"❌ Erreur avec les pages : {e}")
+        print(f"   ❌ Erreur : {e}")
+    
+    # 6. Tester la génération du sitemap
+    print("\n6️⃣  Test de génération du sitemap...")
+    try:
+        from blog.sitemaps import BlogSitemap, CategorySitemap, PageSitemap, StaticViewSitemap
+        
+        blog_sitemap = BlogSitemap()
+        blog_items = list(blog_sitemap.items())
+        print(f"   ✅ BlogSitemap : {len(blog_items)} items")
+        
+        cat_sitemap = CategorySitemap()
+        cat_items = list(cat_sitemap.items())
+        print(f"   ✅ CategorySitemap : {len(cat_items)} items")
+        
+        page_sitemap = PageSitemap()
+        page_items = list(page_sitemap.items())
+        print(f"   ✅ PageSitemap : {len(page_items)} items")
+        
+        static_sitemap = StaticViewSitemap()
+        static_items = list(static_sitemap.items())
+        print(f"   ✅ StaticViewSitemap : {len(static_items)} items")
+        
+        total = len(blog_items) + len(cat_items) + len(page_items) + len(static_items)
+        if total == 0:
+            issues.append("❌ Le sitemap génère 0 items !")
+        
+    except Exception as e:
+        issues.append(f"❌ Erreur lors de la génération : {e}")
+        print(f"   ❌ Erreur : {e}")
+        import traceback
+        traceback.print_exc()
+    
+    # Résumé
+    print("\n" + "="*70)
+    print("RÉSUMÉ DU DIAGNOSTIC")
+    print("="*70 + "\n")
+    
+    if issues:
+        print("❌ PROBLÈMES DÉTECTÉS :\n")
+        for issue in issues:
+            print(f"   {issue}")
+        
+        print("\n" + "="*70)
+        print("SOLUTIONS")
+        print("="*70 + "\n")
+        
+        if "Aucun site configuré" in str(issues):
+            print("🔧 Pour créer le site :")
+            print("""
+python manage.py shell
+>>> from django.contrib.sites.models import Site
+>>> Site.objects.create(id=1, domain='www.duhaz.fr', name='Mr Duhaz')
+>>> exit()
+            """)
+        
+        if "Domaine du site incorrect" in str(issues):
+            print("🔧 Pour corriger le domaine :")
+            print("""
+python manage.py shell
+>>> from django.contrib.sites.models import Site
+>>> site = Site.objects.get(id=1)
+>>> site.domain = 'www.duhaz.fr'
+>>> site.name = 'Mr Duhaz'
+>>> site.save()
+>>> exit()
+            """)
+        
+        if "Aucun article publié" in str(issues):
+            print("⚠️  Vérifiez que vous avez des articles avec b_publier=True")
+        
+        return 1
+    else:
+        print("✅ Aucun problème détecté !")
+        print("\nLe sitemap devrait fonctionner correctement.")
+        print("Si le problème persiste, vérifiez :")
+        print("   - Que le serveur a été redémarré")
+        print("   - Les logs Django pour plus d'infos")
+        return 0
+
+
+if __name__ == "__main__":
+    sys.exit(diagnose_sitemap())

+ 90 - 0
scripts/fix_sitemap_sites.py

@@ -0,0 +1,90 @@
+#!/usr/bin/env python3
+"""
+Script pour configurer automatiquement django.contrib.sites
+Corrige le problème de sitemap vide
+"""
+
+import os
+import sys
+from pathlib import Path
+
+# Ajouter le répertoire parent au path
+sys.path.insert(0, str(Path(__file__).resolve().parent.parent))
+
+# Configuration Django
+os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'duhaz_blog.settings')
+import django
+django.setup()
+
+from django.contrib.sites.models import Site
+
+
+def configure_site():
+    """Configure django.contrib.sites pour le sitemap"""
+    print("\n" + "="*70)
+    print("CONFIGURATION DE DJANGO.CONTRIB.SITES")
+    print("="*70 + "\n")
+    
+    try:
+        # Vérifier si le site existe
+        try:
+            site = Site.objects.get(id=1)
+            print(f"✅ Site existant trouvé :")
+            print(f"   ID: {site.id}")
+            print(f"   Domaine: {site.domain}")
+            print(f"   Nom: {site.name}")
+            
+            # Vérifier si le domaine est correct
+            if site.domain != 'www.duhaz.fr':
+                print(f"\n⚠️  Domaine incorrect : {site.domain}")
+                print(f"   Mise à jour vers : www.duhaz.fr")
+                site.domain = 'www.duhaz.fr'
+                site.name = 'Mr Duhaz'
+                site.save()
+                print("   ✅ Domaine mis à jour !")
+            else:
+                print("\n✅ Domaine correct !")
+                
+        except Site.DoesNotExist:
+            print("⚠️  Aucun site avec ID=1 trouvé")
+            print("   Création du site...")
+            
+            # Créer le site
+            site = Site.objects.create(
+                id=1,
+                domain='www.duhaz.fr',
+                name='Mr Duhaz'
+            )
+            print(f"✅ Site créé avec succès !")
+            print(f"   ID: {site.id}")
+            print(f"   Domaine: {site.domain}")
+            print(f"   Nom: {site.name}")
+        
+        # Vérifier les autres sites
+        all_sites = Site.objects.all()
+        if all_sites.count() > 1:
+            print(f"\n⚠️  {all_sites.count()} sites trouvés :")
+            for s in all_sites:
+                print(f"   - ID: {s.id}, Domaine: {s.domain}")
+            print("\n   Si vous avez des sites inutiles, vous pouvez les supprimer.")
+        
+        print("\n" + "="*70)
+        print("CONFIGURATION TERMINÉE")
+        print("="*70)
+        print("\n✅ django.contrib.sites est maintenant configuré !")
+        print("\n📝 Prochaines étapes :")
+        print("   1. Redémarrer votre serveur Django")
+        print("   2. Vérifier le sitemap : https://www.duhaz.fr/sitemap.xml")
+        print("   3. Exécuter : python scripts/diagnose_sitemap.py")
+        
+        return 0
+        
+    except Exception as e:
+        print(f"\n❌ Erreur : {e}")
+        import traceback
+        traceback.print_exc()
+        return 1
+
+
+if __name__ == "__main__":
+    sys.exit(configure_site())