rinogeek's picture
first commit
fafd0bb
# ============================================
# 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)"