from django import forms
from django.contrib import admin
from django.contrib.contenttypes.models import ContentType
from django.db import models as db_models
from .models import (
DocumentAccessLink,
DocumentAttachment,
DocumentFolder,
DocumentFolderAccessLink,
DocumentFolderAttachment,
DocumentFolderShare,
DocumentShare,
DocumentTag,
DocumentType,
DocumentValidation,
DocumentVersion,
ManagedDocument,
)
@admin.register(DocumentFolder)
class DocumentFolderAdmin(admin.ModelAdmin):
list_display = ("name", "application_label", "is_predefined", "created_by")
list_filter = ("is_predefined", "application_label", "thematics")
search_fields = ("name", "application_label")
filter_horizontal = ("parent_folders", "thematics")
@admin.register(DocumentType)
class DocumentTypeAdmin(admin.ModelAdmin):
list_display = ("code", "label")
search_fields = ("code", "label")
class DocumentTagForm(forms.ModelForm):
"""Limit related_content_types choices to asset models + Project + Intervention."""
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
allowed = ContentType.objects.filter(
db_models.Q(app_label='assets') |
db_models.Q(app_label='projects', model='project') |
db_models.Q(app_label='interventions', model='intervention')
).order_by('app_label', 'model')
self.fields['related_content_types'].queryset = allowed
class Meta:
model = DocumentTag
fields = '__all__'
@admin.register(DocumentTag)
class DocumentTagAdmin(admin.ModelAdmin):
form = DocumentTagForm
list_display = ("name", "slug", "order", "is_unique", "show_in_asset_detail", "display_thematics", "display_related_models")
list_filter = ("is_unique", "show_in_asset_detail", "thematics")
search_fields = ("name_fr", "slug")
filter_horizontal = ("thematics", "related_content_types")
fieldsets = (
(None, {
"fields": ("name_fr", "name_nl", "slug", "order", "is_unique", "show_in_asset_detail"),
}),
("Filtrage", {
"fields": ("thematics", "related_content_types"),
}),
("Paramètres supplémentaires", {
"fields": ("extra_params_schema",),
"description": (
"Définit les champs supplémentaires affichés dans la modale d'upload quand ce tag est sélectionné. "
"Format JSON : liste d'objets avec les clés key, label_fr, "
"label_nl, type (text / number / "
"textarea / select), required (bool), "
"placeholder_fr, placeholder_nl. "
"Pour select : ajouter options (liste d'objets "
"{\"value\", \"label_fr\", \"label_nl\"})."
),
}),
)
def display_thematics(self, obj):
return ", ".join([t.name for t in obj.thematics.all()])
display_thematics.short_description = "Thématiques"
def display_related_models(self, obj):
cts = obj.related_content_types.all()
if not cts:
return "— (tous)"
return ", ".join([f"{ct.app_label}.{ct.model}" for ct in cts])
display_related_models.short_description = "Modèles liés"
class DocumentVersionInline(admin.TabularInline):
model = DocumentVersion
fk_name = "document"
extra = 0
readonly_fields = ("version_number", "uploaded_by", "upload_date")
@admin.register(ManagedDocument)
class ManagedDocumentAdmin(admin.ModelAdmin):
list_display = ("title", "created_by", "updated_at", "is_archived")
list_filter = ("is_archived", "types", "tags")
search_fields = ("title", "description")
inlines = [DocumentVersionInline]
@admin.register(DocumentVersion)
class DocumentVersionAdmin(admin.ModelAdmin):
list_display = ("document", "version_number", "uploaded_by", "upload_date", "status")
list_filter = ("status",)
search_fields = ("document__title", "comment")
@admin.register(DocumentValidation)
class DocumentValidationAdmin(admin.ModelAdmin):
list_display = ("version", "role", "status", "validated_by", "validated_at")
list_filter = ("status", "role")
@admin.register(DocumentShare)
class DocumentShareAdmin(admin.ModelAdmin):
list_display = ("document", "user", "permission", "created_at")
list_filter = ("permission",)
@admin.register(DocumentFolderShare)
class DocumentFolderShareAdmin(admin.ModelAdmin):
list_display = ("folder", "user", "permission", "created_at")
list_filter = ("permission",)
@admin.register(DocumentFolderAccessLink)
class DocumentFolderAccessLinkAdmin(admin.ModelAdmin):
list_display = ("folder", "permission", "expires_at", "created_at")
list_filter = ("permission",)
search_fields = ("token",)
@admin.register(DocumentAccessLink)
class DocumentAccessLinkAdmin(admin.ModelAdmin):
list_display = ("document", "permission", "expires_at", "created_at")
list_filter = ("permission",)
search_fields = ("token",)
@admin.register(DocumentAttachment)
class DocumentAttachmentAdmin(admin.ModelAdmin):
list_display = ("document", "content_type", "object_id", "attached_at")
list_filter = ("content_type",)
search_fields = ("document__title",)
@admin.register(DocumentFolderAttachment)
class DocumentFolderAttachmentAdmin(admin.ModelAdmin):
"""Admin générique pour voir tous les liens dossier-objet."""
list_display = ("folder", "content_type", "object_id", "get_object_display", "is_default", "attached_at")
list_filter = ("is_default", "content_type", "folder")
search_fields = ("folder__name",)
autocomplete_fields = ['folder']
readonly_fields = ('get_object_display',)
def get_object_display(self, obj):
"""Affiche l'objet lié."""
if obj.content_object:
return str(obj.content_object)
return f"ID {obj.object_id} (supprimé)"
get_object_display.short_description = "Objet lié"