views.py 8.1 KB

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