admin.py 7.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240
  1. from django.contrib import admin
  2. from django.db import models
  3. from django.forms import ModelForm, BaseInlineFormSet
  4. from django.utils import timezone
  5. from django.core.urlresolvers import reverse
  6. from django.utils.html import format_html
  7. from django.core.mail import mail_managers
  8. from adhesions.models import Adhesion
  9. from djadhere.utils import get_active_filter
  10. from .models import Service, ServiceType, IPResource, Route, ResourceAllocation
  11. from .utils import notify_allocation
  12. ### Filters
  13. class ResourceInUseFilter(admin.SimpleListFilter):
  14. title = 'disponibilité'
  15. parameter_name = 'available'
  16. def lookups(self, request, model_admin):
  17. return (
  18. (1, 'Disponible'),
  19. (0, 'Non disponible'),
  20. )
  21. def queryset(self, request, queryset):
  22. now = timezone.now()
  23. active_filter = get_active_filter('allocation')
  24. if self.value() == '0': # non disponible
  25. return queryset.filter(active_filter | models.Q(reserved=True))
  26. if self.value() == '1': # disponible
  27. return queryset.exclude(reserved=True).exclude(active_filter)
  28. class AllocationStatusFilter(admin.SimpleListFilter):
  29. title = 'statut'
  30. parameter_name = 'status'
  31. def lookups(self, request, model_admin):
  32. return (
  33. (1, 'En cours'),
  34. (0, 'Terminée'),
  35. )
  36. def queryset(self, request, queryset):
  37. now = timezone.now()
  38. active_filter = get_active_filter()
  39. if self.value() == '0': # inactif
  40. return queryset.exclude(active_filter)
  41. if self.value() == '1': # actif
  42. return queryset.filter(active_filter)
  43. ### Helpers
  44. def get_foreignkey_link_func(field):
  45. def foreignkey_link(self, instance):
  46. obj = getattr(instance, field)
  47. url = reverse('admin:%s_%s_change' % (obj._meta.app_label,
  48. obj._meta.model_name),
  49. args=(obj.pk,))
  50. return format_html(u'<a href="{}">{}</a>', url, str(obj))
  51. return foreignkey_link
  52. ### Inlines
  53. class ResourceAllocationInlineFormSet(BaseInlineFormSet):
  54. def save_new(self, form, commit=True):
  55. obj = super().save_new(form, commit)
  56. notify_allocation(self.request, obj)
  57. return obj
  58. def save_existing(self, form, instance, commit=True):
  59. old = ResourceAllocation.objects.get(pk=instance.pk)
  60. notify_allocation(self.request, instance, old)
  61. return super().save_existing(form, instance, commit)
  62. class AllocationInline(admin.TabularInline):
  63. model = ResourceAllocation
  64. formset = ResourceAllocationInlineFormSet
  65. extra = 0
  66. fields = ('id', 'service', 'resource', 'route', 'start', 'end')
  67. raw_id_fields = ('service', 'resource',)
  68. verbose_name_plural = 'Allocations'
  69. show_change_link = True
  70. def get_formset(self, request, obj=None, **kwargs):
  71. formset = super().get_formset(request, obj, **kwargs)
  72. formset.request = request
  73. return formset
  74. def get_max_num(self, request, obj=None, **kwargs):
  75. existing = obj.allocations.count() if obj else 0
  76. # pour simplifier la validation, on ajoute qu’une allocation à la fois
  77. # il faudrait surcharger la méthode clean du formset pour supprimer cette limite
  78. return existing + 1
  79. def has_delete_permission(self, request, obj=None):
  80. return False
  81. ### Actions
  82. def ends_resource(resource, request, queryset):
  83. now = timezone.now()
  84. queryset.exclude(start__lte=now, end__isnull=False).update(end=now)
  85. # TODO: send mail
  86. ends_resource.short_description = 'Terminer les allocations sélectionnées'
  87. ### ModelAdmin
  88. class ServiceAdmin(admin.ModelAdmin):
  89. list_display = ('id', 'get_adhesion_link', 'get_adherent_link', 'service_type', 'label', 'active')
  90. list_filter = (
  91. 'active',
  92. ('service_type', admin.RelatedOnlyFieldListFilter),
  93. )
  94. inlines = (AllocationInline,)
  95. search_fields = ('id', 'service_type__name', 'label', 'adhesion__id',)
  96. raw_id_fields = ('adhesion',)
  97. get_adhesion_link = get_foreignkey_link_func('adhesion')
  98. get_adhesion_link.short_description = 'Numéro d’adhésion'
  99. get_adherent_link = lambda self, service: service.adhesion.get_adherent_link()
  100. get_adherent_link.short_description = Adhesion.get_adherent_link.short_description
  101. def get_actions(self, request):
  102. actions = super().get_actions(request)
  103. if 'delete_selected' in actions:
  104. del actions['delete_selected']
  105. return actions
  106. def has_delete_permission(self, request, obj=None):
  107. return False
  108. class IPResourceAdmin(admin.ModelAdmin):
  109. list_display = ('__str__', 'available_display')
  110. list_filter = (
  111. ResourceInUseFilter,
  112. ('prefixes', admin.RelatedOnlyFieldListFilter),
  113. )
  114. fields = ('ip', 'reserved',)
  115. readonly_fields = ('ip', 'reserved',)
  116. search_fields = ('ip',)
  117. inlines = (AllocationInline,)
  118. def available_display(self, obj):
  119. return not obj.reserved and not obj.in_use
  120. available_display.short_description = 'Disponible'
  121. available_display.boolean = True
  122. def get_actions(self, request):
  123. actions = super().get_actions(request)
  124. if 'delete_selected' in actions:
  125. del actions['delete_selected']
  126. return actions
  127. def has_add_permission(self, request, obj=None):
  128. return False
  129. def has_delete_permission(self, request, obj=None):
  130. return False
  131. class RouteAdmin(admin.ModelAdmin):
  132. fields = ('name',)
  133. readonly_fields = ('name',)
  134. def has_add_permission(self, request, obj=None):
  135. return False
  136. def get_actions(self, request):
  137. actions = super().get_actions(request)
  138. if 'delete_selected' in actions:
  139. del actions['delete_selected']
  140. return actions
  141. def has_delete_permission(self, request, obj=None):
  142. return False
  143. class ResourceAllocationAdmin(admin.ModelAdmin):
  144. list_display = ('id', 'resource_link', 'service_link', 'start', 'end',)
  145. list_filter = (AllocationStatusFilter,)
  146. #actions = (ends_resource,)
  147. raw_id_fields = ('resource', 'service',)
  148. search_fields = ('resource__ip', 'service__id', 'service__service_type__name', 'service__label')
  149. resource_link = get_foreignkey_link_func('resource')
  150. resource_link.short_description = 'Ressource'
  151. service_link = get_foreignkey_link_func('service')
  152. service_link.short_description = 'Service'
  153. def get_actions(self, request):
  154. actions = super().get_actions(request)
  155. if 'delete_selected' in actions:
  156. del actions['delete_selected']
  157. return actions
  158. def has_delete_permission(self, request, obj=None):
  159. return False
  160. def save_model(self, request, obj, form, change):
  161. if change:
  162. old_alloc = ResourceAllocation.objects.get(pk=obj.pk)
  163. else:
  164. old_alloc = None
  165. super().save_model(request, obj, form, change)
  166. notify_allocation(request, obj, old_alloc)
  167. class ServiceTypeAdmin(admin.ModelAdmin):
  168. fields = ('name',)
  169. readonly_fields = ('name',)
  170. def get_actions(self, request):
  171. actions = super().get_actions(request)
  172. if 'delete_selected' in actions:
  173. del actions['delete_selected']
  174. return actions
  175. def has_add_permission(self, request, obj=None):
  176. return False
  177. def has_delete_permission(self, request, obj=None):
  178. return False
  179. admin.site.register(ServiceType, ServiceTypeAdmin)
  180. admin.site.register(Service, ServiceAdmin)
  181. admin.site.register(IPResource, IPResourceAdmin)
  182. admin.site.register(Route, RouteAdmin)
  183. admin.site.register(ResourceAllocation, ResourceAllocationAdmin)