File size: 4,174 Bytes
fafd0bb
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
# ============================================
# apps/analytics/models.py - Analytics & Search Tracking
# ============================================
from django.db import models
from apps.core.models import TimestampMixin
from apps.users.models import User

class SearchLog(TimestampMixin):
    """
    Enregistre chaque recherche effectuée sur la plateforme
    pour analyser les intérêts et comportements des utilisateurs
    """
    CATEGORY_CHOICES = [
        ('QUESTIONS', 'Questions du Forum'),
        ('MENTORS', 'Recherche de Mentors'),
        ('OPPORTUNITIES', 'Opportunités'),
        ('TOOLS', 'Outils Pédagogiques'),
        ('USERS', 'Utilisateurs'),
        ('GENERAL', 'Recherche Générale'),
    ]
    
    # Qui a effectué la recherche
    user = models.ForeignKey(
        User, 
        on_delete=models.SET_NULL, 
        null=True, 
        blank=True,
        related_name='search_logs',
        help_text="Utilisateur qui a effectué la recherche (null si anonyme)"
    )
    
    # Catégorie de la recherche
    category = models.CharField(
        max_length=20, 
        choices=CATEGORY_CHOICES,
        db_index=True,
        help_text="Type de contenu recherché"
    )
    
    # Terme de recherche
    search_query = models.CharField(
        max_length=500,
        db_index=True,
        help_text="Texte saisi par l'utilisateur"
    )
    
    # Filtres appliqués (JSON pour flexibilité)
    filters_applied = models.JSONField(
        default=dict,
        blank=True,
        help_text="Filtres appliqués lors de la recherche (ex: {\"status\": \"solved\", \"tags\": [\"math\"]})"
    )
    
    # Résultats
    results_count = models.IntegerField(
        default=0,
        help_text="Nombre de résultats retournés"
    )
    
    # Métadonnées de session
    session_id = models.CharField(
        max_length=100,
        blank=True,
        db_index=True,
        help_text="ID de session pour regrouper les recherches d'une même visite"
    )
    
    ip_address = models.GenericIPAddressField(
        null=True,
        blank=True,
        help_text="Adresse IP de l'utilisateur"
    )
    
    user_agent = models.TextField(
        blank=True,
        help_text="User agent du navigateur"
    )
    
    # Page d'origine
    page_url = models.CharField(
        max_length=500,
        blank=True,
        help_text="URL de la page où la recherche a été effectuée"
    )
    
    # Interaction
    clicked_result_id = models.CharField(
        max_length=100,
        null=True,
        blank=True,
        help_text="ID du résultat cliqué (si applicable)"
    )
    
    clicked_result_position = models.IntegerField(
        null=True,
        blank=True,
        help_text="Position du résultat cliqué dans la liste"
    )
    
    class Meta:
        db_table = 'search_logs'
        verbose_name = 'Recherche'
        verbose_name_plural = 'Recherches'
        indexes = [
            models.Index(fields=['category', '-created_at']),
            models.Index(fields=['user', '-created_at']),
            models.Index(fields=['search_query']),
            models.Index(fields=['-created_at']),
        ]
        ordering = ['-created_at']
    
    def __str__(self):
        user_info = self.user.email if self.user else "Anonyme"
        return f"{user_info} - {self.category}: '{self.search_query}'"


class PopularSearch(models.Model):
    """
    Vue matérialisée des recherches les plus populaires
    Mise à jour périodiquement pour optimiser les performances
    """
    category = models.CharField(max_length=20, choices=SearchLog.CATEGORY_CHOICES)
    search_query = models.CharField(max_length=500)
    search_count = models.IntegerField(default=0)
    last_searched = models.DateTimeField(auto_now=True)
    
    class Meta:
        db_table = 'popular_searches'
        verbose_name = 'Recherche Populaire'
        verbose_name_plural = 'Recherches Populaires'
        unique_together = ['category', 'search_query']
        ordering = ['-search_count', '-last_searched']
    
    def __str__(self):
        return f"{self.category}: '{self.search_query}' ({self.search_count}x)"