from django.contrib import admin from django.utils.html import format_html from django.urls import reverse from django.db import models from mptt.admin import MPTTModelAdmin from .models import Equipment, Category, Location ### Inlines class EquipmentInline(admin.TabularInline): model = Equipment class ExistingEquipmentInline(EquipmentInline): max_num = 0 fields = ('location', 'category', 'quantity',) readonly_fields = ('location', 'category',) def get_queryset(self, request): qs = super().get_queryset(request) qs = qs.select_related('location', 'category',) return qs class NewEquipmentInline(admin.TabularInline): model = Equipment extra = 0 verbose_name_plural = 'Nouveaux équipements' def get_queryset(self, request): return Equipment.objects.none() ### Filters class CategoryFilter(admin.SimpleListFilter): title = 'Catégorie' parameter_name = 'category' def lookups(self, request, model_admin): return [ (c.pk, '    ' * c.get_level() + c.name) for c in Category.objects.all() ] def queryset(self, request, queryset): try: category = Category.objects.get(pk=int(self.value())) except (TypeError, ValueError, Category.DoesNotExist): pass else: categories = category.get_descendants(include_self=True) queryset = queryset.filter(category__in=categories) return queryset ### Mixins class StockMixin: search_fields = ('name',) list_display = ('__str__', 'quantity',) inlines = (ExistingEquipmentInline, NewEquipmentInline,) def get_queryset(self, request): qs = super().get_queryset(request) qs = qs.annotate(quantity=models.Sum('equipments__quantity')) return qs def quantity(self, category): return category.quantity quantity.short_description = 'Quantité' quantity.admin_order_field = 'quantity' def get_actions(self, request): actions = super().get_actions(request) if 'delete_selected' in actions: del actions['delete_selected'] return actions ### Admins class CategoryAdmin(StockMixin, MPTTModelAdmin): def has_delete_permission(self, request, obj=None): # Interdiction de supprimer la catégorie si elle contient des équipements return obj \ and not obj.get_descendants().exists \ and not Equipment.objects.filter(category__in=obj.get_descendants(include_self=True)).exists() class LocationAdmin(StockMixin, admin.ModelAdmin): def has_delete_permission(self, request, obj=None): # Interdiction de supprimer l’emplacement si il contient des équipements return obj and not obj.equipments.exists() #class EquipmentAdmin(admin.ModelAdmin): # list_display = ('location', 'category', 'quantity',) # list_display_links = ('location', 'category',) # list_editable = ('quantity',) # list_filter = ( # ('location', admin.RelatedOnlyFieldListFilter), # CategoryFilter, # ) # # def get_actions(self, request): # actions = super().get_actions(request) # if 'delete_selected' in actions: # del actions['delete_selected'] # return actions # # def has_delete_permission(self, request, obj=None): # # Interdiction de supprimer le stock d’équipements s’il n’est pas vide # return obj and obj.quantity == 0 admin.site.register(Category, CategoryAdmin) admin.site.register(Location, LocationAdmin) #admin.site.register(Equipment, EquipmentAdmin)