admin.py 3.5 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697
  1. from django.contrib import admin
  2. from django.utils.html import format_html
  3. from django.urls import reverse
  4. from mptt.admin import MPTTModelAdmin
  5. from .models import Equipment, Category, Location
  6. class EquipmentInline(admin.StackedInline):
  7. model = Equipment
  8. list_display = ('location', 'category', 'quantity',)
  9. class CategoryFilter(admin.SimpleListFilter):
  10. title = 'Catégorie'
  11. parameter_name = 'category'
  12. def lookups(self, request, model_admin):
  13. return [ (c.pk, '    ' * c.get_level() + c.name) for c in Category.objects.all() ]
  14. def queryset(self, request, queryset):
  15. try:
  16. category = Category.objects.get(pk=int(self.value()))
  17. except (TypeError, ValueError, Category.DoesNotExist):
  18. pass
  19. else:
  20. categories = category.get_descendants(include_self=True)
  21. queryset = queryset.filter(category__in=categories)
  22. return queryset
  23. class CategoryAdmin(MPTTModelAdmin):
  24. search_fields = ['name']
  25. list_display = ('__str__', 'equipement_list_link',)
  26. def equipement_list_link(self, category):
  27. url = reverse('admin:%s_%s_changelist' % (Equipment._meta.app_label, Equipment._meta.model_name))
  28. url += '?category=%d' % category.pk
  29. return format_html(u'<a href="{}">{}</a>', url, 'voir la liste des équipements')
  30. equipement_list_link.short_description = 'Équipements'
  31. def get_actions(self, request):
  32. actions = super().get_actions(request)
  33. if 'delete_selected' in actions:
  34. del actions['delete_selected']
  35. return actions
  36. def has_delete_permission(self, request, obj=None):
  37. # Interdiction de supprimer la catégorie si elle contient des équipements
  38. return obj and not Equipment.objects.filter(category__in=obj.get_descendants(include_self=True)).exists()
  39. class LocationAdmin(admin.ModelAdmin):
  40. list_display = ('__str__', 'equipement_list_link',)
  41. inlines = (EquipmentInline,)
  42. def equipement_list_link(self, location):
  43. url = reverse('admin:%s_%s_changelist' % (Equipment._meta.app_label, Equipment._meta.model_name))
  44. url += '?location__id__exact=%d' % location.pk
  45. return format_html(u'<a href="{}">{}</a>', url, 'voir la liste des équipements')
  46. equipement_list_link.short_description = 'Équipements'
  47. def get_actions(self, request):
  48. actions = super().get_actions(request)
  49. if 'delete_selected' in actions:
  50. del actions['delete_selected']
  51. return actions
  52. def has_delete_permission(self, request, obj=None):
  53. # Interdiction de supprimer l’emplacement si il contient des équipements
  54. return obj and not obj.equipment_set.exists()
  55. class EquipmentAdmin(admin.ModelAdmin):
  56. list_display = ('location', 'category', 'quantity',)
  57. list_display_links = ('location', 'category',)
  58. list_editable = ('quantity',)
  59. list_filter = (
  60. ('location', admin.RelatedOnlyFieldListFilter),
  61. CategoryFilter,
  62. )
  63. def get_actions(self, request):
  64. actions = super().get_actions(request)
  65. if 'delete_selected' in actions:
  66. del actions['delete_selected']
  67. return actions
  68. def has_delete_permission(self, request, obj=None):
  69. # Interdiction de supprimer le stock d’équipements s’il n’est pas vide
  70. return obj and obj.quantity == 0
  71. admin.site.register(Category, CategoryAdmin)
  72. admin.site.register(Location, LocationAdmin)
  73. admin.site.register(Equipment, EquipmentAdmin)