Ajout de la vue stats_charts avec graphiques détaillés pour les superadministrateurs, mise à jour des templates et des routes associées, et configuration supplémentaire pour l'email backend.
This commit is contained in:
parent
083af6f9d4
commit
7869abf441
4 changed files with 102 additions and 1 deletions
|
|
@ -7,4 +7,5 @@ urlpatterns = [
|
|||
path('premium/<int:course_id>', views.premium, name='premium'),
|
||||
# Tableau de bord statistiques (réservé superadministrateurs)
|
||||
path('dashboard/stats/', views.stats_dashboard, name='stats_dashboard'),
|
||||
path('dashboard/stats/charts/', views.stats_charts, name='stats_charts'),
|
||||
]
|
||||
|
|
@ -199,3 +199,97 @@ def stats_dashboard(request):
|
|||
context['labels_json'] = json.dumps(context['series']['days'])
|
||||
|
||||
return render(request, 'home/stats_dashboard.html', context)
|
||||
|
||||
|
||||
@user_passes_test(lambda u: u.is_superuser)
|
||||
@cache_page(60 * 15)
|
||||
def stats_charts(request):
|
||||
"""Page dédiée aux graphiques (réservée superadmins)."""
|
||||
# Période
|
||||
period_options = [7, 30, 90, 180]
|
||||
try:
|
||||
p = int(request.GET.get('p', 30))
|
||||
except ValueError:
|
||||
p = 30
|
||||
if p not in period_options:
|
||||
p = 30
|
||||
|
||||
now = timezone.now()
|
||||
start_dt = now - timezone.timedelta(days=p-1)
|
||||
period_start_date = start_dt.date()
|
||||
period_end_date = now.date()
|
||||
|
||||
# Trafic par jour (visiteurs uniques)
|
||||
visits_qs = (
|
||||
Visit.objects
|
||||
.filter(date__gte=period_start_date, date__lte=period_end_date)
|
||||
.values('date')
|
||||
.annotate(c=Count('visitor_id', distinct=True))
|
||||
.order_by('date')
|
||||
)
|
||||
|
||||
# Conversions par jour (visiteurs devenus utilisateurs)
|
||||
conversions_qs = (
|
||||
Visit.objects
|
||||
.filter(
|
||||
became_user_at__isnull=False,
|
||||
became_user_at__date__gte=period_start_date,
|
||||
became_user_at__date__lte=period_end_date,
|
||||
)
|
||||
.extra(select={'day': "date(became_user_at)"})
|
||||
.values('day')
|
||||
.annotate(c=Count('visitor_id', distinct=True))
|
||||
.order_by('day')
|
||||
)
|
||||
|
||||
def build_series_dict(qs, date_key='date', count_key='c'):
|
||||
counts = {str(item[date_key]): item[count_key] for item in qs}
|
||||
days = []
|
||||
values = []
|
||||
d = period_start_date
|
||||
while d <= period_end_date:
|
||||
key = str(d)
|
||||
days.append(key)
|
||||
values.append(counts.get(key, 0))
|
||||
d += timezone.timedelta(days=1)
|
||||
return days, values
|
||||
|
||||
labels, visitors_series = build_series_dict(visits_qs, date_key='date')
|
||||
_, conversions_series = build_series_dict(conversions_qs, date_key='day')
|
||||
|
||||
# Sources & Pays (sur la période)
|
||||
period_visits = Visit.objects.filter(date__gte=period_start_date, date__lte=period_end_date)
|
||||
top_sources_qs = (
|
||||
period_visits
|
||||
.values('source')
|
||||
.annotate(c=Count('visitor_id', distinct=True))
|
||||
.order_by('-c')[:10]
|
||||
)
|
||||
top_countries_qs = (
|
||||
period_visits
|
||||
.exclude(country='')
|
||||
.values('country')
|
||||
.annotate(c=Count('visitor_id', distinct=True))
|
||||
.order_by('-c')[:10]
|
||||
)
|
||||
|
||||
sources_labels = [(row['source'] or 'Direct/Unknown') for row in top_sources_qs]
|
||||
sources_values = [row['c'] for row in top_sources_qs]
|
||||
countries_labels = [row['country'] for row in top_countries_qs]
|
||||
countries_values = [row['c'] for row in top_countries_qs]
|
||||
|
||||
context = {
|
||||
'period_options': period_options,
|
||||
'p': p,
|
||||
'start_date': period_start_date,
|
||||
'end_date': period_end_date,
|
||||
'labels_json': json.dumps(labels),
|
||||
'visitors_series_json': json.dumps(visitors_series),
|
||||
'conversions_series_json': json.dumps(conversions_series),
|
||||
'sources_labels_json': json.dumps(sources_labels),
|
||||
'sources_values_json': json.dumps(sources_values),
|
||||
'countries_labels_json': json.dumps(countries_labels),
|
||||
'countries_values_json': json.dumps(countries_values),
|
||||
}
|
||||
|
||||
return render(request, 'home/stats_charts.html', context)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue