Coverage for sm/views_audit.py: 93%
45 statements
« prev ^ index » next coverage.py v7.17.0, created at 2026-10-24 19:06 +0000
« prev ^ index » next coverage.py v7.17.0, created at 2026-10-24 19:06 +0000
1from django.contrib.auth.mixins import LoginRequiredMixin
2from django.db.models import Q
3from django.views.generic import ListView
4from typing import Any
6from .utils_permissions import APP_MODELS
9class AuditLogView(LoginRequiredMixin, ListView):
10 """
11 Per-tenant audit log: lists history records across all core models,
12 filtered by the user's groups (or a specific selected group).
13 """
15 template_name = "audit_log.html"
16 context_object_name = "entries"
17 paginate_by = 50
19 def get_group(self):
20 group_id = self.request.GET.get("group")
21 if not group_id or not group_id.isdigit():
22 return None
23 return int(group_id)
25 def get_queryset(self):
26 user = self.request.user
27 group_filter = self.get_group()
29 entries = []
30 for app_label, _model_name in APP_MODELS:
31 try:
32 from django.apps import apps
34 model = apps.get_model(app_label, "Model")
35 except LookupError:
36 continue
37 if not hasattr(model, "history"):
38 continue
40 qs = model.history.all()
41 if not user.is_superuser:
42 user_groups = user.groups.all()
43 qs = qs.filter(Q(group_id__in=user_groups) | Q(group_id__isnull=True))
44 if group_filter:
45 qs = qs.filter(group_id=group_filter)
47 for record in qs.select_related("history_user")[:100]:
48 entries.append(
49 {
50 "date": record.history_date,
51 "user": (
52 record.history_user
53 if getattr(record, "history_user_id", None)
54 else None
55 ),
56 "user_id": getattr(record, "history_user_id", None),
57 "action": record.history_type,
58 "model": model._meta.verbose_name,
59 "object": record,
60 "group_id": getattr(record, "group_id", None),
61 "group_name": (
62 record.group.name
63 if getattr(record, "group_id", None) and record.group_id
64 else None
65 ),
66 }
67 )
69 entries.sort(key=lambda e: e["date"], reverse=True)
70 return entries
72 def get_context_data(self, **kwargs: Any) -> Any:
73 context = super().get_context_data(**kwargs)
74 user = self.request.user
75 if user.is_superuser:
76 from django.contrib.auth.models import Group
78 context["groups"] = Group.objects.all()
79 else:
80 context["groups"] = user.groups.all()
81 context["selected_group"] = self.get_group()
82 return context