"""
Configuration de l'interface d'administration Django
Créé par Marino ATOHOUN - FireWatch AI Project
Amélioré par BlackBenAI Team pour un contrôle avancé
"""
from django.contrib import admin
from django.utils.html import format_html
from django.urls import reverse
from django.utils.safestring import mark_safe
from .models import Contact, DetectionSession, Detection, AIModelStatus
# Actions personnalisées
@admin.action(description='Marquer comme lu')
def make_read(modeladmin, request, queryset):
queryset.update(is_read=True)
@admin.action(description='Marquer comme non lu')
def make_unread(modeladmin, request, queryset):
queryset.update(is_read=False)
@admin.register(Contact)
class ContactAdmin(admin.ModelAdmin):
"""Administration des contacts - Par Marino ATOHOUN & BlackBenAI"""
list_display = ('name', 'email', 'created_at', 'is_read', 'message_preview')
list_filter = ('is_read', 'created_at')
search_fields = ('name', 'email', 'message')
readonly_fields = ('created_at',)
list_editable = ('is_read',)
ordering = ('-created_at',)
actions = [make_read, make_unread]
list_per_page = 20
def message_preview(self, obj):
"""Aperçu du message"""
return obj.message[:50] + "..." if len(obj.message) > 50 else obj.message
message_preview.short_description = "Aperçu du message"
fieldsets = (
('Informations de contact', {
'fields': ('name', 'email')
}),
('Message', {
'fields': ('message',)
}),
('Statut', {
'fields': ('is_read', 'created_at')
}),
)
class DetectionInline(admin.TabularInline):
"""Inline pour afficher les détections dans une session"""
model = Detection
extra = 0
readonly_fields = ('class_name', 'confidence', 'bbox_x', 'bbox_y', 'bbox_width', 'bbox_height', 'frame_number', 'timestamp')
can_delete = False
show_change_link = True
@admin.register(DetectionSession)
class DetectionSessionAdmin(admin.ModelAdmin):
"""Administration des sessions de détection - Par Marino ATOHOUN & BlackBenAI"""
list_display = ('session_id_short', 'detection_type', 'created_at', 'is_processed', 'processing_time_display', 'detections_count', 'preview_image')
list_filter = ('detection_type', 'is_processed', 'created_at')
search_fields = ('session_id',)
readonly_fields = ('session_id', 'created_at', 'processing_time', 'preview_original', 'preview_result')
inlines = [DetectionInline]
ordering = ('-created_at',)
list_per_page = 20
date_hierarchy = 'created_at'
def session_id_short(self, obj):
return str(obj.session_id)[:8] + "..."
session_id_short.short_description = "ID Session"
def processing_time_display(self, obj):
if obj.processing_time:
return f"{obj.processing_time:.2f}s"
return "-"
processing_time_display.short_description = "Temps"
def detections_count(self, obj):
"""Nombre de détections dans la session"""
count = obj.detections.count()
color = "green" if count > 0 else "gray"
return format_html('{}', color, count)
detections_count.short_description = "Détections"
def preview_image(self, obj):
if obj.result_file:
return format_html('', obj.result_file.url)
elif obj.original_file and obj.detection_type == 'image':
return format_html('
', obj.original_file.url)
return "-"
preview_image.short_description = "Aperçu"
def preview_original(self, obj):
if obj.original_file:
if obj.detection_type == 'image':
return format_html('
', obj.original_file.url, obj.original_file.url)
elif obj.detection_type == 'video':
return format_html('', obj.original_file.url)
return "Aucun fichier"
preview_original.short_description = "Fichier original"
def preview_result(self, obj):
if obj.result_file:
return format_html('
', obj.result_file.url, obj.result_file.url)
return "Aucun résultat"
preview_result.short_description = "Résultat de détection"
fieldsets = (
('Informations de session', {
'fields': ('session_id', 'detection_type', 'created_at')
}),
('Aperçu des fichiers', {
'fields': ('preview_original', 'preview_result'),
'description': 'Aperçu visuel des fichiers traités'
}),
('Fichiers bruts', {
'fields': ('original_file', 'result_file'),
'classes': ('collapse',)
}),
('Métriques de traitement', {
'fields': ('is_processed', 'processing_time')
}),
)
@admin.register(Detection)
class DetectionAdmin(admin.ModelAdmin):
"""Administration des détections - Par Marino ATOHOUN & BlackBenAI"""
list_display = ('id', 'session_link', 'class_name_colored', 'confidence_bar', 'frame_number', 'bbox_preview')
list_filter = ('class_name', 'session__detection_type', 'session__created_at')
search_fields = ('session__session_id', 'class_name')
readonly_fields = ('session', 'class_name', 'confidence', 'bbox_x', 'bbox_y', 'bbox_width', 'bbox_height', 'bbox_visual')
ordering = ('-session__created_at', 'frame_number')
list_per_page = 50
def session_link(self, obj):
url = reverse("admin:detection_detectionsession_change", args=[obj.session.id])
return format_html('Session {}', url, str(obj.session.session_id)[:8])
session_link.short_description = "Session"
def class_name_colored(self, obj):
colors = {
'fire': 'red',
'smoke': 'gray',
'person': 'orange',
'intrusion': 'orange',
'vehicle': 'blue'
}
color = colors.get(obj.class_name, 'black')
return format_html('{}', color, obj.get_class_name_display())
class_name_colored.short_description = "Classe"
def confidence_bar(self, obj):
"""Barre de progression visuelle pour la confiance"""
percent = obj.confidence * 100
color = "green" if percent > 80 else "orange" if percent > 50 else "red"
return format_html(
'