views.py 8.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233
  1. from django.contrib import messages
  2. from django.contrib.auth.decorators import permission_required
  3. from django.contrib.auth.mixins import PermissionRequiredMixin
  4. from django.db import transaction
  5. from django.db.models import Count
  6. from django.shortcuts import get_object_or_404, redirect, render
  7. from extras.models import Graph, GRAPH_TYPE_PROVIDER
  8. from utilities.forms import ConfirmationForm
  9. from utilities.views import (
  10. BulkDeleteView, BulkEditView, BulkImportView, ObjectDeleteView, ObjectEditView, ObjectListView,
  11. )
  12. from . import filters, forms, tables
  13. from .models import Circuit, CircuitTermination, CircuitType, Provider, TERM_SIDE_A, TERM_SIDE_Z
  14. #
  15. # Providers
  16. #
  17. class ProviderListView(ObjectListView):
  18. queryset = Provider.objects.annotate(count_circuits=Count('circuits'))
  19. filter = filters.ProviderFilter
  20. filter_form = forms.ProviderFilterForm
  21. table = tables.ProviderTable
  22. edit_permissions = ['circuits.change_provider', 'circuits.delete_provider']
  23. template_name = 'circuits/provider_list.html'
  24. def provider(request, slug):
  25. provider = get_object_or_404(Provider, slug=slug)
  26. circuits = Circuit.objects.filter(provider=provider)
  27. show_graphs = Graph.objects.filter(type=GRAPH_TYPE_PROVIDER).exists()
  28. return render(request, 'circuits/provider.html', {
  29. 'provider': provider,
  30. 'circuits': circuits,
  31. 'show_graphs': show_graphs,
  32. })
  33. class ProviderEditView(PermissionRequiredMixin, ObjectEditView):
  34. permission_required = 'circuits.change_provider'
  35. model = Provider
  36. form_class = forms.ProviderForm
  37. template_name = 'circuits/provider_edit.html'
  38. obj_list_url = 'circuits:provider_list'
  39. class ProviderDeleteView(PermissionRequiredMixin, ObjectDeleteView):
  40. permission_required = 'circuits.delete_provider'
  41. model = Provider
  42. redirect_url = 'circuits:provider_list'
  43. class ProviderBulkImportView(PermissionRequiredMixin, BulkImportView):
  44. permission_required = 'circuits.add_provider'
  45. form = forms.ProviderImportForm
  46. table = tables.ProviderTable
  47. template_name = 'circuits/provider_import.html'
  48. obj_list_url = 'circuits:provider_list'
  49. class ProviderBulkEditView(PermissionRequiredMixin, BulkEditView):
  50. permission_required = 'circuits.change_provider'
  51. cls = Provider
  52. form = forms.ProviderBulkEditForm
  53. template_name = 'circuits/provider_bulk_edit.html'
  54. default_redirect_url = 'circuits:provider_list'
  55. class ProviderBulkDeleteView(PermissionRequiredMixin, BulkDeleteView):
  56. permission_required = 'circuits.delete_provider'
  57. cls = Provider
  58. default_redirect_url = 'circuits:provider_list'
  59. #
  60. # Circuit Types
  61. #
  62. class CircuitTypeListView(ObjectListView):
  63. queryset = CircuitType.objects.annotate(circuit_count=Count('circuits'))
  64. table = tables.CircuitTypeTable
  65. edit_permissions = ['circuits.change_circuittype', 'circuits.delete_circuittype']
  66. template_name = 'circuits/circuittype_list.html'
  67. class CircuitTypeEditView(PermissionRequiredMixin, ObjectEditView):
  68. permission_required = 'circuits.change_circuittype'
  69. model = CircuitType
  70. form_class = forms.CircuitTypeForm
  71. obj_list_url = 'circuits:circuittype_list'
  72. use_obj_view = False
  73. class CircuitTypeBulkDeleteView(PermissionRequiredMixin, BulkDeleteView):
  74. permission_required = 'circuits.delete_circuittype'
  75. cls = CircuitType
  76. default_redirect_url = 'circuits:circuittype_list'
  77. #
  78. # Circuits
  79. #
  80. class CircuitListView(ObjectListView):
  81. queryset = Circuit.objects.select_related('provider', 'type', 'tenant').prefetch_related('terminations__site')
  82. filter = filters.CircuitFilter
  83. filter_form = forms.CircuitFilterForm
  84. table = tables.CircuitTable
  85. edit_permissions = ['circuits.change_circuit', 'circuits.delete_circuit']
  86. template_name = 'circuits/circuit_list.html'
  87. def circuit(request, pk):
  88. circuit = get_object_or_404(Circuit, pk=pk)
  89. termination_a = CircuitTermination.objects.filter(circuit=circuit, term_side=TERM_SIDE_A).first()
  90. termination_z = CircuitTermination.objects.filter(circuit=circuit, term_side=TERM_SIDE_Z).first()
  91. return render(request, 'circuits/circuit.html', {
  92. 'circuit': circuit,
  93. 'termination_a': termination_a,
  94. 'termination_z': termination_z,
  95. })
  96. class CircuitEditView(PermissionRequiredMixin, ObjectEditView):
  97. permission_required = 'circuits.change_circuit'
  98. model = Circuit
  99. form_class = forms.CircuitForm
  100. fields_initial = ['provider']
  101. template_name = 'circuits/circuit_edit.html'
  102. obj_list_url = 'circuits:circuit_list'
  103. class CircuitDeleteView(PermissionRequiredMixin, ObjectDeleteView):
  104. permission_required = 'circuits.delete_circuit'
  105. model = Circuit
  106. redirect_url = 'circuits:circuit_list'
  107. class CircuitBulkImportView(PermissionRequiredMixin, BulkImportView):
  108. permission_required = 'circuits.add_circuit'
  109. form = forms.CircuitImportForm
  110. table = tables.CircuitTable
  111. template_name = 'circuits/circuit_import.html'
  112. obj_list_url = 'circuits:circuit_list'
  113. class CircuitBulkEditView(PermissionRequiredMixin, BulkEditView):
  114. permission_required = 'circuits.change_circuit'
  115. cls = Circuit
  116. form = forms.CircuitBulkEditForm
  117. template_name = 'circuits/circuit_bulk_edit.html'
  118. default_redirect_url = 'circuits:circuit_list'
  119. class CircuitBulkDeleteView(PermissionRequiredMixin, BulkDeleteView):
  120. permission_required = 'circuits.delete_circuit'
  121. cls = Circuit
  122. default_redirect_url = 'circuits:circuit_list'
  123. @permission_required('circuits.change_circuittermination')
  124. def circuit_terminations_swap(request, pk):
  125. circuit = get_object_or_404(Circuit, pk=pk)
  126. termination_a = CircuitTermination.objects.filter(circuit=circuit, term_side=TERM_SIDE_A).first()
  127. termination_z = CircuitTermination.objects.filter(circuit=circuit, term_side=TERM_SIDE_Z).first()
  128. if not termination_a and not termination_z:
  129. messages.error(request, "No terminations have been defined for circuit {}.".format(circuit))
  130. return redirect('circuits:circuit', pk=circuit.pk)
  131. if request.method == 'POST':
  132. form = ConfirmationForm(request.POST)
  133. if form.is_valid():
  134. if termination_a and termination_z:
  135. # Use a placeholder to avoid an IntegrityError on the (circuit, term_side) unique constraint
  136. with transaction.atomic():
  137. termination_a.term_side = '_'
  138. termination_a.save()
  139. termination_z.term_side = 'A'
  140. termination_z.save()
  141. termination_a.term_side = 'Z'
  142. termination_a.save()
  143. elif termination_a:
  144. termination_a.term_side = 'Z'
  145. termination_a.save()
  146. else:
  147. termination_z.term_side = 'A'
  148. termination_z.save()
  149. messages.success(request, "Swapped terminations for circuit {}.".format(circuit))
  150. return redirect('circuits:circuit', pk=circuit.pk)
  151. else:
  152. form = ConfirmationForm()
  153. return render(request, 'circuits/circuit_terminations_swap.html', {
  154. 'circuit': circuit,
  155. 'termination_a': termination_a,
  156. 'termination_z': termination_z,
  157. 'form': form,
  158. 'panel_class': 'default',
  159. 'button_class': 'primary',
  160. 'cancel_url': circuit.get_absolute_url(),
  161. })
  162. #
  163. # Circuit terminations
  164. #
  165. class CircuitTerminationEditView(PermissionRequiredMixin, ObjectEditView):
  166. permission_required = 'circuits.change_circuittermination'
  167. model = CircuitTermination
  168. form_class = forms.CircuitTerminationForm
  169. fields_initial = ['term_side']
  170. template_name = 'circuits/circuittermination_edit.html'
  171. def alter_obj(self, obj, args, kwargs):
  172. if 'circuit' in kwargs:
  173. circuit = get_object_or_404(Circuit, pk=kwargs['circuit'])
  174. obj.circuit = circuit
  175. return obj
  176. class CircuitTerminationDeleteView(PermissionRequiredMixin, ObjectDeleteView):
  177. permission_required = 'circuits.delete_circuittermination'
  178. model = CircuitTermination