admin.py 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117
  1. from django.contrib import admin
  2. from django.utils.html import format_html
  3. from django.urls import reverse
  4. from django.db import models
  5. from mptt.admin import MPTTModelAdmin
  6. from .models import Equipment, Category, Location
  7. ### Inlines
  8. class EquipmentInline(admin.TabularInline):
  9. model = Equipment
  10. class ExistingEquipmentInline(EquipmentInline):
  11. max_num = 0
  12. fields = ('location', 'category', 'quantity',)
  13. readonly_fields = ('location', 'category',)
  14. def get_queryset(self, request):
  15. qs = super().get_queryset(request)
  16. qs = qs.select_related('location', 'category',)
  17. return qs
  18. class NewEquipmentInline(admin.TabularInline):
  19. model = Equipment
  20. extra = 0
  21. verbose_name_plural = 'Nouveaux équipements'
  22. def get_queryset(self, request):
  23. return Equipment.objects.none()
  24. ### Filters
  25. class CategoryFilter(admin.SimpleListFilter):
  26. title = 'Catégorie'
  27. parameter_name = 'category'
  28. def lookups(self, request, model_admin):
  29. return [ (c.pk, '    ' * c.get_level() + c.name) for c in Category.objects.all() ]
  30. def queryset(self, request, queryset):
  31. try:
  32. category = Category.objects.get(pk=int(self.value()))
  33. except (TypeError, ValueError, Category.DoesNotExist):
  34. pass
  35. else:
  36. categories = category.get_descendants(include_self=True)
  37. queryset = queryset.filter(category__in=categories)
  38. return queryset
  39. ### Mixins
  40. class StockMixin:
  41. search_fields = ('name',)
  42. list_display = ('__str__', 'quantity',)
  43. inlines = (ExistingEquipmentInline, NewEquipmentInline,)
  44. def get_queryset(self, request):
  45. qs = super().get_queryset(request)
  46. qs = qs.annotate(quantity=models.Sum('equipments__quantity'))
  47. return qs
  48. def quantity(self, category):
  49. return category.quantity
  50. quantity.short_description = 'Quantité'
  51. quantity.admin_order_field = 'quantity'
  52. def get_actions(self, request):
  53. actions = super().get_actions(request)
  54. if 'delete_selected' in actions:
  55. del actions['delete_selected']
  56. return actions
  57. ### Admins
  58. class CategoryAdmin(StockMixin, MPTTModelAdmin):
  59. def has_delete_permission(self, request, obj=None):
  60. # Interdiction de supprimer la catégorie si elle contient des équipements
  61. return obj \
  62. and not obj.get_descendants().exists \
  63. and not Equipment.objects.filter(category__in=obj.get_descendants(include_self=True)).exists()
  64. class LocationAdmin(StockMixin, admin.ModelAdmin):
  65. def has_delete_permission(self, request, obj=None):
  66. # Interdiction de supprimer l’emplacement si il contient des équipements
  67. return obj and not obj.equipments.exists()
  68. #class EquipmentAdmin(admin.ModelAdmin):
  69. # list_display = ('location', 'category', 'quantity',)
  70. # list_display_links = ('location', 'category',)
  71. # list_editable = ('quantity',)
  72. # list_filter = (
  73. # ('location', admin.RelatedOnlyFieldListFilter),
  74. # CategoryFilter,
  75. # )
  76. #
  77. # def get_actions(self, request):
  78. # actions = super().get_actions(request)
  79. # if 'delete_selected' in actions:
  80. # del actions['delete_selected']
  81. # return actions
  82. #
  83. # def has_delete_permission(self, request, obj=None):
  84. # # Interdiction de supprimer le stock d’équipements s’il n’est pas vide
  85. # return obj and obj.quantity == 0
  86. admin.site.register(Category, CategoryAdmin)
  87. admin.site.register(Location, LocationAdmin)
  88. #admin.site.register(Equipment, EquipmentAdmin)