views.py 28 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801
  1. from django.contrib import messages
  2. from django.db import router, transaction
  3. from django.shortcuts import get_object_or_404, redirect, render
  4. from django.utils.translation import gettext_lazy as _
  5. from dcim.views import PathTraceView
  6. from ipam.models import ASN
  7. from netbox.object_actions import AddObject, BulkDelete, BulkEdit, BulkExport, BulkImport
  8. from netbox.views import generic
  9. from utilities.forms import ConfirmationForm
  10. from utilities.query import count_related
  11. from utilities.views import GetRelatedModelsMixin, register_model_view
  12. from . import filtersets, forms, tables
  13. from .models import *
  14. #
  15. # Providers
  16. #
  17. @register_model_view(Provider, 'list', path='', detail=False)
  18. class ProviderListView(generic.ObjectListView):
  19. queryset = Provider.objects.annotate(
  20. count_circuits=count_related(Circuit, 'provider'),
  21. asn_count=count_related(ASN, 'providers'),
  22. account_count=count_related(ProviderAccount, 'provider'),
  23. )
  24. filterset = filtersets.ProviderFilterSet
  25. filterset_form = forms.ProviderFilterForm
  26. table = tables.ProviderTable
  27. @register_model_view(Provider)
  28. class ProviderView(GetRelatedModelsMixin, generic.ObjectView):
  29. queryset = Provider.objects.all()
  30. def get_extra_context(self, request, instance):
  31. return {
  32. 'related_models': self.get_related_models(
  33. request,
  34. instance,
  35. omit=(),
  36. extra=(
  37. (
  38. VirtualCircuit.objects.restrict(request.user, 'view').filter(
  39. provider_network__provider=instance
  40. ),
  41. 'provider_id',
  42. ),
  43. ),
  44. ),
  45. }
  46. @register_model_view(Provider, 'add', detail=False)
  47. @register_model_view(Provider, 'edit')
  48. class ProviderEditView(generic.ObjectEditView):
  49. queryset = Provider.objects.all()
  50. form = forms.ProviderForm
  51. @register_model_view(Provider, 'delete')
  52. class ProviderDeleteView(generic.ObjectDeleteView):
  53. queryset = Provider.objects.all()
  54. @register_model_view(Provider, 'bulk_import', path='import', detail=False)
  55. class ProviderBulkImportView(generic.BulkImportView):
  56. queryset = Provider.objects.all()
  57. model_form = forms.ProviderImportForm
  58. @register_model_view(Provider, 'bulk_edit', path='edit', detail=False)
  59. class ProviderBulkEditView(generic.BulkEditView):
  60. queryset = Provider.objects.annotate(
  61. count_circuits=count_related(Circuit, 'provider')
  62. )
  63. filterset = filtersets.ProviderFilterSet
  64. table = tables.ProviderTable
  65. form = forms.ProviderBulkEditForm
  66. @register_model_view(Provider, 'bulk_rename', path='rename', detail=False)
  67. class ProviderBulkRenameView(generic.BulkRenameView):
  68. queryset = Provider.objects.all()
  69. @register_model_view(Provider, 'bulk_delete', path='delete', detail=False)
  70. class ProviderBulkDeleteView(generic.BulkDeleteView):
  71. queryset = Provider.objects.annotate(
  72. count_circuits=count_related(Circuit, 'provider')
  73. )
  74. filterset = filtersets.ProviderFilterSet
  75. table = tables.ProviderTable
  76. #
  77. # ProviderAccounts
  78. #
  79. @register_model_view(ProviderAccount, 'list', path='', detail=False)
  80. class ProviderAccountListView(generic.ObjectListView):
  81. queryset = ProviderAccount.objects.annotate(
  82. count_circuits=count_related(Circuit, 'provider_account')
  83. )
  84. filterset = filtersets.ProviderAccountFilterSet
  85. filterset_form = forms.ProviderAccountFilterForm
  86. table = tables.ProviderAccountTable
  87. @register_model_view(ProviderAccount)
  88. class ProviderAccountView(GetRelatedModelsMixin, generic.ObjectView):
  89. queryset = ProviderAccount.objects.all()
  90. def get_extra_context(self, request, instance):
  91. return {
  92. 'related_models': self.get_related_models(request, instance),
  93. }
  94. @register_model_view(ProviderAccount, 'add', detail=False)
  95. @register_model_view(ProviderAccount, 'edit')
  96. class ProviderAccountEditView(generic.ObjectEditView):
  97. queryset = ProviderAccount.objects.all()
  98. form = forms.ProviderAccountForm
  99. @register_model_view(ProviderAccount, 'delete')
  100. class ProviderAccountDeleteView(generic.ObjectDeleteView):
  101. queryset = ProviderAccount.objects.all()
  102. @register_model_view(ProviderAccount, 'bulk_import', path='import', detail=False)
  103. class ProviderAccountBulkImportView(generic.BulkImportView):
  104. queryset = ProviderAccount.objects.all()
  105. model_form = forms.ProviderAccountImportForm
  106. table = tables.ProviderAccountTable
  107. @register_model_view(ProviderAccount, 'bulk_edit', path='edit', detail=False)
  108. class ProviderAccountBulkEditView(generic.BulkEditView):
  109. queryset = ProviderAccount.objects.annotate(
  110. count_circuits=count_related(Circuit, 'provider_account')
  111. )
  112. filterset = filtersets.ProviderAccountFilterSet
  113. table = tables.ProviderAccountTable
  114. form = forms.ProviderAccountBulkEditForm
  115. @register_model_view(ProviderAccount, 'bulk_rename', path='rename', detail=False)
  116. class ProviderAccountBulkRenameView(generic.BulkRenameView):
  117. queryset = ProviderAccount.objects.all()
  118. @register_model_view(ProviderAccount, 'bulk_delete', path='delete', detail=False)
  119. class ProviderAccountBulkDeleteView(generic.BulkDeleteView):
  120. queryset = ProviderAccount.objects.annotate(
  121. count_circuits=count_related(Circuit, 'provider_account')
  122. )
  123. filterset = filtersets.ProviderAccountFilterSet
  124. table = tables.ProviderAccountTable
  125. #
  126. # Provider networks
  127. #
  128. @register_model_view(ProviderNetwork, 'list', path='', detail=False)
  129. class ProviderNetworkListView(generic.ObjectListView):
  130. queryset = ProviderNetwork.objects.all()
  131. filterset = filtersets.ProviderNetworkFilterSet
  132. filterset_form = forms.ProviderNetworkFilterForm
  133. table = tables.ProviderNetworkTable
  134. @register_model_view(ProviderNetwork)
  135. class ProviderNetworkView(GetRelatedModelsMixin, generic.ObjectView):
  136. queryset = ProviderNetwork.objects.all()
  137. def get_extra_context(self, request, instance):
  138. return {
  139. 'related_models': self.get_related_models(
  140. request,
  141. instance,
  142. omit=(CircuitTermination,),
  143. extra=(
  144. (
  145. Circuit.objects.restrict(request.user, 'view').filter(terminations___provider_network=instance),
  146. 'provider_network_id',
  147. ),
  148. (
  149. CircuitTermination.objects.restrict(request.user, 'view').filter(_provider_network=instance),
  150. 'provider_network_id',
  151. ),
  152. ),
  153. ),
  154. }
  155. @register_model_view(ProviderNetwork, 'add', detail=False)
  156. @register_model_view(ProviderNetwork, 'edit')
  157. class ProviderNetworkEditView(generic.ObjectEditView):
  158. queryset = ProviderNetwork.objects.all()
  159. form = forms.ProviderNetworkForm
  160. @register_model_view(ProviderNetwork, 'delete')
  161. class ProviderNetworkDeleteView(generic.ObjectDeleteView):
  162. queryset = ProviderNetwork.objects.all()
  163. @register_model_view(ProviderNetwork, 'bulk_import', path='import', detail=False)
  164. class ProviderNetworkBulkImportView(generic.BulkImportView):
  165. queryset = ProviderNetwork.objects.all()
  166. model_form = forms.ProviderNetworkImportForm
  167. @register_model_view(ProviderNetwork, 'bulk_edit', path='edit', detail=False)
  168. class ProviderNetworkBulkEditView(generic.BulkEditView):
  169. queryset = ProviderNetwork.objects.all()
  170. filterset = filtersets.ProviderNetworkFilterSet
  171. table = tables.ProviderNetworkTable
  172. form = forms.ProviderNetworkBulkEditForm
  173. @register_model_view(ProviderNetwork, 'bulk_rename', path='rename', detail=False)
  174. class ProviderNetworkBulkRenameView(generic.BulkRenameView):
  175. queryset = ProviderNetwork.objects.all()
  176. @register_model_view(ProviderNetwork, 'bulk_delete', path='delete', detail=False)
  177. class ProviderNetworkBulkDeleteView(generic.BulkDeleteView):
  178. queryset = ProviderNetwork.objects.all()
  179. filterset = filtersets.ProviderNetworkFilterSet
  180. table = tables.ProviderNetworkTable
  181. #
  182. # Circuit Types
  183. #
  184. @register_model_view(CircuitType, 'list', path='', detail=False)
  185. class CircuitTypeListView(generic.ObjectListView):
  186. queryset = CircuitType.objects.annotate(
  187. circuit_count=count_related(Circuit, 'type')
  188. )
  189. filterset = filtersets.CircuitTypeFilterSet
  190. filterset_form = forms.CircuitTypeFilterForm
  191. table = tables.CircuitTypeTable
  192. @register_model_view(CircuitType)
  193. class CircuitTypeView(GetRelatedModelsMixin, generic.ObjectView):
  194. queryset = CircuitType.objects.all()
  195. def get_extra_context(self, request, instance):
  196. return {
  197. 'related_models': self.get_related_models(request, instance),
  198. }
  199. @register_model_view(CircuitType, 'add', detail=False)
  200. @register_model_view(CircuitType, 'edit')
  201. class CircuitTypeEditView(generic.ObjectEditView):
  202. queryset = CircuitType.objects.all()
  203. form = forms.CircuitTypeForm
  204. @register_model_view(CircuitType, 'delete')
  205. class CircuitTypeDeleteView(generic.ObjectDeleteView):
  206. queryset = CircuitType.objects.all()
  207. @register_model_view(CircuitType, 'bulk_import', path='import', detail=False)
  208. class CircuitTypeBulkImportView(generic.BulkImportView):
  209. queryset = CircuitType.objects.all()
  210. model_form = forms.CircuitTypeImportForm
  211. @register_model_view(CircuitType, 'bulk_edit', path='edit', detail=False)
  212. class CircuitTypeBulkEditView(generic.BulkEditView):
  213. queryset = CircuitType.objects.annotate(
  214. circuit_count=count_related(Circuit, 'type')
  215. )
  216. filterset = filtersets.CircuitTypeFilterSet
  217. table = tables.CircuitTypeTable
  218. form = forms.CircuitTypeBulkEditForm
  219. @register_model_view(CircuitType, 'bulk_rename', path='rename', detail=False)
  220. class CircuitTypeBulkRenameView(generic.BulkRenameView):
  221. queryset = CircuitType.objects.all()
  222. @register_model_view(CircuitType, 'bulk_delete', path='delete', detail=False)
  223. class CircuitTypeBulkDeleteView(generic.BulkDeleteView):
  224. queryset = CircuitType.objects.annotate(
  225. circuit_count=count_related(Circuit, 'type')
  226. )
  227. filterset = filtersets.CircuitTypeFilterSet
  228. table = tables.CircuitTypeTable
  229. #
  230. # Circuits
  231. #
  232. @register_model_view(Circuit, 'list', path='', detail=False)
  233. class CircuitListView(generic.ObjectListView):
  234. queryset = Circuit.objects.prefetch_related(
  235. 'tenant__group', 'termination_a__termination', 'termination_z__termination',
  236. )
  237. filterset = filtersets.CircuitFilterSet
  238. filterset_form = forms.CircuitFilterForm
  239. table = tables.CircuitTable
  240. @register_model_view(Circuit)
  241. class CircuitView(generic.ObjectView):
  242. queryset = Circuit.objects.all()
  243. @register_model_view(Circuit, 'add', detail=False)
  244. @register_model_view(Circuit, 'edit')
  245. class CircuitEditView(generic.ObjectEditView):
  246. queryset = Circuit.objects.all()
  247. form = forms.CircuitForm
  248. @register_model_view(Circuit, 'delete')
  249. class CircuitDeleteView(generic.ObjectDeleteView):
  250. queryset = Circuit.objects.all()
  251. @register_model_view(Circuit, 'bulk_import', path='import', detail=False)
  252. class CircuitBulkImportView(generic.BulkImportView):
  253. queryset = Circuit.objects.all()
  254. model_form = forms.CircuitImportForm
  255. additional_permissions = [
  256. 'circuits.add_circuittermination',
  257. ]
  258. related_object_forms = {
  259. 'terminations': forms.CircuitTerminationImportRelatedForm,
  260. }
  261. def prep_related_object_data(self, parent, data):
  262. data.update({'circuit': parent})
  263. return data
  264. @register_model_view(Circuit, 'bulk_edit', path='edit', detail=False)
  265. class CircuitBulkEditView(generic.BulkEditView):
  266. queryset = Circuit.objects.prefetch_related(
  267. 'tenant__group', 'termination_a__termination', 'termination_z__termination',
  268. )
  269. filterset = filtersets.CircuitFilterSet
  270. table = tables.CircuitTable
  271. form = forms.CircuitBulkEditForm
  272. @register_model_view(Circuit, 'bulk_rename', path='rename', detail=False)
  273. class CircuitBulkRenameView(generic.BulkRenameView):
  274. queryset = Circuit.objects.all()
  275. field_name = 'cid'
  276. @register_model_view(Circuit, 'bulk_delete', path='delete', detail=False)
  277. class CircuitBulkDeleteView(generic.BulkDeleteView):
  278. queryset = Circuit.objects.prefetch_related(
  279. 'tenant__group', 'termination_a__termination', 'termination_z__termination',
  280. )
  281. filterset = filtersets.CircuitFilterSet
  282. table = tables.CircuitTable
  283. class CircuitSwapTerminations(generic.ObjectEditView):
  284. """
  285. Swap the A and Z terminations of a circuit.
  286. """
  287. queryset = Circuit.objects.all()
  288. def get(self, request, pk):
  289. circuit = get_object_or_404(self.queryset, pk=pk)
  290. form = ConfirmationForm()
  291. # Circuit must have at least one termination to swap
  292. if not circuit.termination_a and not circuit.termination_z:
  293. messages.error(request, _(
  294. "No terminations have been defined for circuit {circuit}."
  295. ).format(circuit=circuit))
  296. return redirect('circuits:circuit', pk=circuit.pk)
  297. return render(request, 'circuits/circuit_terminations_swap.html', {
  298. 'circuit': circuit,
  299. 'termination_a': circuit.termination_a,
  300. 'termination_z': circuit.termination_z,
  301. 'form': form,
  302. 'panel_class': 'light',
  303. 'button_class': 'primary',
  304. 'return_url': circuit.get_absolute_url(),
  305. })
  306. def post(self, request, pk):
  307. circuit = get_object_or_404(self.queryset, pk=pk)
  308. form = ConfirmationForm(request.POST)
  309. if form.is_valid():
  310. termination_a = CircuitTermination.objects.filter(pk=circuit.termination_a_id).first()
  311. termination_z = CircuitTermination.objects.filter(pk=circuit.termination_z_id).first()
  312. if termination_a and termination_z:
  313. # Use a placeholder to avoid an IntegrityError on the (circuit, term_side) unique constraint
  314. with transaction.atomic(using=router.db_for_write(CircuitTermination)):
  315. termination_a.term_side = '_'
  316. termination_a.save()
  317. termination_z.term_side = 'A'
  318. termination_z.save()
  319. termination_a.term_side = 'Z'
  320. termination_a.save()
  321. circuit.refresh_from_db()
  322. circuit.termination_a = termination_z
  323. circuit.termination_z = termination_a
  324. circuit.save()
  325. elif termination_a:
  326. termination_a.term_side = 'Z'
  327. termination_a.save()
  328. circuit.refresh_from_db()
  329. circuit.termination_a = None
  330. circuit.save()
  331. else:
  332. termination_z.term_side = 'A'
  333. termination_z.save()
  334. circuit.refresh_from_db()
  335. circuit.termination_z = None
  336. circuit.save()
  337. messages.success(request, _("Swapped terminations for circuit {circuit}.").format(circuit=circuit))
  338. return redirect('circuits:circuit', pk=circuit.pk)
  339. return render(request, 'circuits/circuit_terminations_swap.html', {
  340. 'circuit': circuit,
  341. 'termination_a': circuit.termination_a,
  342. 'termination_z': circuit.termination_z,
  343. 'form': form,
  344. 'panel_class': 'default',
  345. 'button_class': 'primary',
  346. 'return_url': circuit.get_absolute_url(),
  347. })
  348. #
  349. # Circuit terminations
  350. #
  351. @register_model_view(CircuitTermination, 'list', path='', detail=False)
  352. class CircuitTerminationListView(generic.ObjectListView):
  353. queryset = CircuitTermination.objects.all()
  354. filterset = filtersets.CircuitTerminationFilterSet
  355. filterset_form = forms.CircuitTerminationFilterForm
  356. table = tables.CircuitTerminationTable
  357. actions = (AddObject, BulkImport, BulkExport, BulkEdit, BulkDelete)
  358. @register_model_view(CircuitTermination)
  359. class CircuitTerminationView(generic.ObjectView):
  360. queryset = CircuitTermination.objects.all()
  361. @register_model_view(CircuitTermination, 'add', detail=False)
  362. @register_model_view(CircuitTermination, 'edit')
  363. class CircuitTerminationEditView(generic.ObjectEditView):
  364. queryset = CircuitTermination.objects.all()
  365. form = forms.CircuitTerminationForm
  366. @register_model_view(CircuitTermination, 'delete')
  367. class CircuitTerminationDeleteView(generic.ObjectDeleteView):
  368. queryset = CircuitTermination.objects.all()
  369. @register_model_view(CircuitTermination, 'bulk_import', path='import', detail=False)
  370. class CircuitTerminationBulkImportView(generic.BulkImportView):
  371. queryset = CircuitTermination.objects.all()
  372. model_form = forms.CircuitTerminationImportForm
  373. @register_model_view(CircuitTermination, 'bulk_edit', path='edit', detail=False)
  374. class CircuitTerminationBulkEditView(generic.BulkEditView):
  375. queryset = CircuitTermination.objects.all()
  376. filterset = filtersets.CircuitTerminationFilterSet
  377. table = tables.CircuitTerminationTable
  378. form = forms.CircuitTerminationBulkEditForm
  379. @register_model_view(CircuitTermination, 'bulk_delete', path='delete', detail=False)
  380. class CircuitTerminationBulkDeleteView(generic.BulkDeleteView):
  381. queryset = CircuitTermination.objects.all()
  382. filterset = filtersets.CircuitTerminationFilterSet
  383. table = tables.CircuitTerminationTable
  384. # Trace view
  385. register_model_view(CircuitTermination, 'trace', kwargs={'model': CircuitTermination})(PathTraceView)
  386. #
  387. # Circuit Groups
  388. #
  389. @register_model_view(CircuitGroup, 'list', path='', detail=False)
  390. class CircuitGroupListView(generic.ObjectListView):
  391. queryset = CircuitGroup.objects.annotate(
  392. circuit_group_assignment_count=count_related(CircuitGroupAssignment, 'group')
  393. )
  394. filterset = filtersets.CircuitGroupFilterSet
  395. filterset_form = forms.CircuitGroupFilterForm
  396. table = tables.CircuitGroupTable
  397. @register_model_view(CircuitGroup)
  398. class CircuitGroupView(GetRelatedModelsMixin, generic.ObjectView):
  399. queryset = CircuitGroup.objects.all()
  400. def get_extra_context(self, request, instance):
  401. return {
  402. 'related_models': self.get_related_models(request, instance),
  403. }
  404. @register_model_view(CircuitGroup, 'add', detail=False)
  405. @register_model_view(CircuitGroup, 'edit')
  406. class CircuitGroupEditView(generic.ObjectEditView):
  407. queryset = CircuitGroup.objects.all()
  408. form = forms.CircuitGroupForm
  409. @register_model_view(CircuitGroup, 'delete')
  410. class CircuitGroupDeleteView(generic.ObjectDeleteView):
  411. queryset = CircuitGroup.objects.all()
  412. @register_model_view(CircuitGroup, 'bulk_import', path='import', detail=False)
  413. class CircuitGroupBulkImportView(generic.BulkImportView):
  414. queryset = CircuitGroup.objects.all()
  415. model_form = forms.CircuitGroupImportForm
  416. @register_model_view(CircuitGroup, 'bulk_edit', path='edit', detail=False)
  417. class CircuitGroupBulkEditView(generic.BulkEditView):
  418. queryset = CircuitGroup.objects.all()
  419. filterset = filtersets.CircuitGroupFilterSet
  420. table = tables.CircuitGroupTable
  421. form = forms.CircuitGroupBulkEditForm
  422. @register_model_view(CircuitGroup, 'bulk_rename', path='rename', detail=False)
  423. class CircuitGroupBulkRenameView(generic.BulkRenameView):
  424. queryset = CircuitGroup.objects.all()
  425. @register_model_view(CircuitGroup, 'bulk_delete', path='delete', detail=False)
  426. class CircuitGroupBulkDeleteView(generic.BulkDeleteView):
  427. queryset = CircuitGroup.objects.all()
  428. filterset = filtersets.CircuitGroupFilterSet
  429. table = tables.CircuitGroupTable
  430. #
  431. # Circuit Groups
  432. #
  433. @register_model_view(CircuitGroupAssignment, 'list', path='', detail=False)
  434. class CircuitGroupAssignmentListView(generic.ObjectListView):
  435. queryset = CircuitGroupAssignment.objects.all()
  436. filterset = filtersets.CircuitGroupAssignmentFilterSet
  437. filterset_form = forms.CircuitGroupAssignmentFilterForm
  438. table = tables.CircuitGroupAssignmentTable
  439. actions = (AddObject, BulkImport, BulkExport, BulkEdit, BulkDelete)
  440. @register_model_view(CircuitGroupAssignment)
  441. class CircuitGroupAssignmentView(generic.ObjectView):
  442. queryset = CircuitGroupAssignment.objects.all()
  443. @register_model_view(CircuitGroupAssignment, 'add', detail=False)
  444. @register_model_view(CircuitGroupAssignment, 'edit')
  445. class CircuitGroupAssignmentEditView(generic.ObjectEditView):
  446. queryset = CircuitGroupAssignment.objects.all()
  447. form = forms.CircuitGroupAssignmentForm
  448. @register_model_view(CircuitGroupAssignment, 'delete')
  449. class CircuitGroupAssignmentDeleteView(generic.ObjectDeleteView):
  450. queryset = CircuitGroupAssignment.objects.all()
  451. @register_model_view(CircuitGroupAssignment, 'bulk_import', path='import', detail=False)
  452. class CircuitGroupAssignmentBulkImportView(generic.BulkImportView):
  453. queryset = CircuitGroupAssignment.objects.all()
  454. model_form = forms.CircuitGroupAssignmentImportForm
  455. @register_model_view(CircuitGroupAssignment, 'bulk_edit', path='edit', detail=False)
  456. class CircuitGroupAssignmentBulkEditView(generic.BulkEditView):
  457. queryset = CircuitGroupAssignment.objects.all()
  458. filterset = filtersets.CircuitGroupAssignmentFilterSet
  459. table = tables.CircuitGroupAssignmentTable
  460. form = forms.CircuitGroupAssignmentBulkEditForm
  461. @register_model_view(CircuitGroupAssignment, 'bulk_delete', path='delete', detail=False)
  462. class CircuitGroupAssignmentBulkDeleteView(generic.BulkDeleteView):
  463. queryset = CircuitGroupAssignment.objects.all()
  464. filterset = filtersets.CircuitGroupAssignmentFilterSet
  465. table = tables.CircuitGroupAssignmentTable
  466. #
  467. # Virtual circuit Types
  468. #
  469. @register_model_view(VirtualCircuitType, 'list', path='', detail=False)
  470. class VirtualCircuitTypeListView(generic.ObjectListView):
  471. queryset = VirtualCircuitType.objects.annotate(
  472. virtual_circuit_count=count_related(VirtualCircuit, 'type')
  473. )
  474. filterset = filtersets.VirtualCircuitTypeFilterSet
  475. filterset_form = forms.VirtualCircuitTypeFilterForm
  476. table = tables.VirtualCircuitTypeTable
  477. @register_model_view(VirtualCircuitType)
  478. class VirtualCircuitTypeView(GetRelatedModelsMixin, generic.ObjectView):
  479. queryset = VirtualCircuitType.objects.all()
  480. def get_extra_context(self, request, instance):
  481. return {
  482. 'related_models': self.get_related_models(request, instance),
  483. }
  484. @register_model_view(VirtualCircuitType, 'add', detail=False)
  485. @register_model_view(VirtualCircuitType, 'edit')
  486. class VirtualCircuitTypeEditView(generic.ObjectEditView):
  487. queryset = VirtualCircuitType.objects.all()
  488. form = forms.VirtualCircuitTypeForm
  489. @register_model_view(VirtualCircuitType, 'delete')
  490. class VirtualCircuitTypeDeleteView(generic.ObjectDeleteView):
  491. queryset = VirtualCircuitType.objects.all()
  492. @register_model_view(VirtualCircuitType, 'bulk_import', path='import', detail=False)
  493. class VirtualCircuitTypeBulkImportView(generic.BulkImportView):
  494. queryset = VirtualCircuitType.objects.all()
  495. model_form = forms.VirtualCircuitTypeImportForm
  496. @register_model_view(VirtualCircuitType, 'bulk_edit', path='edit', detail=False)
  497. class VirtualCircuitTypeBulkEditView(generic.BulkEditView):
  498. queryset = VirtualCircuitType.objects.annotate(
  499. circuit_count=count_related(Circuit, 'type')
  500. )
  501. filterset = filtersets.VirtualCircuitTypeFilterSet
  502. table = tables.VirtualCircuitTypeTable
  503. form = forms.VirtualCircuitTypeBulkEditForm
  504. @register_model_view(VirtualCircuitType, 'bulk_rename', path='rename', detail=False)
  505. class VirtualCircuitTypeBulkRenameView(generic.BulkRenameView):
  506. queryset = VirtualCircuitType.objects.all()
  507. @register_model_view(VirtualCircuitType, 'bulk_delete', path='delete', detail=False)
  508. class VirtualCircuitTypeBulkDeleteView(generic.BulkDeleteView):
  509. queryset = VirtualCircuitType.objects.annotate(
  510. circuit_count=count_related(Circuit, 'type')
  511. )
  512. filterset = filtersets.VirtualCircuitTypeFilterSet
  513. table = tables.VirtualCircuitTypeTable
  514. #
  515. # Virtual circuits
  516. #
  517. @register_model_view(VirtualCircuit, 'list', path='', detail=False)
  518. class VirtualCircuitListView(generic.ObjectListView):
  519. queryset = VirtualCircuit.objects.annotate(
  520. termination_count=count_related(VirtualCircuitTermination, 'virtual_circuit')
  521. )
  522. filterset = filtersets.VirtualCircuitFilterSet
  523. filterset_form = forms.VirtualCircuitFilterForm
  524. table = tables.VirtualCircuitTable
  525. @register_model_view(VirtualCircuit)
  526. class VirtualCircuitView(generic.ObjectView):
  527. queryset = VirtualCircuit.objects.all()
  528. @register_model_view(VirtualCircuit, 'add', detail=False)
  529. @register_model_view(VirtualCircuit, 'edit')
  530. class VirtualCircuitEditView(generic.ObjectEditView):
  531. queryset = VirtualCircuit.objects.all()
  532. form = forms.VirtualCircuitForm
  533. @register_model_view(VirtualCircuit, 'delete')
  534. class VirtualCircuitDeleteView(generic.ObjectDeleteView):
  535. queryset = VirtualCircuit.objects.all()
  536. @register_model_view(VirtualCircuit, 'bulk_import', path='import', detail=False)
  537. class VirtualCircuitBulkImportView(generic.BulkImportView):
  538. queryset = VirtualCircuit.objects.all()
  539. model_form = forms.VirtualCircuitImportForm
  540. additional_permissions = [
  541. 'circuits.add_virtualcircuittermination',
  542. ]
  543. related_object_forms = {
  544. 'terminations': forms.VirtualCircuitTerminationImportRelatedForm,
  545. }
  546. def prep_related_object_data(self, parent, data):
  547. data.update({'virtual_circuit': parent})
  548. return data
  549. @register_model_view(VirtualCircuit, 'bulk_edit', path='edit', detail=False)
  550. class VirtualCircuitBulkEditView(generic.BulkEditView):
  551. queryset = VirtualCircuit.objects.annotate(
  552. termination_count=count_related(VirtualCircuitTermination, 'virtual_circuit')
  553. )
  554. filterset = filtersets.VirtualCircuitFilterSet
  555. table = tables.VirtualCircuitTable
  556. form = forms.VirtualCircuitBulkEditForm
  557. @register_model_view(VirtualCircuit, 'bulk_rename', path='rename', detail=False)
  558. class VirtualCircuitBulkRenameView(generic.BulkRenameView):
  559. queryset = VirtualCircuit.objects.all()
  560. field_name = 'cid'
  561. @register_model_view(VirtualCircuit, 'bulk_delete', path='delete', detail=False)
  562. class VirtualCircuitBulkDeleteView(generic.BulkDeleteView):
  563. queryset = VirtualCircuit.objects.annotate(
  564. termination_count=count_related(VirtualCircuitTermination, 'virtual_circuit')
  565. )
  566. filterset = filtersets.VirtualCircuitFilterSet
  567. table = tables.VirtualCircuitTable
  568. #
  569. # Virtual circuit terminations
  570. #
  571. class VirtualCircuitTerminationListView(generic.ObjectListView):
  572. queryset = VirtualCircuitTermination.objects.all()
  573. filterset = filtersets.VirtualCircuitTerminationFilterSet
  574. filterset_form = forms.VirtualCircuitTerminationFilterForm
  575. table = tables.VirtualCircuitTerminationTable
  576. actions = (AddObject, BulkImport, BulkExport, BulkEdit, BulkDelete)
  577. @register_model_view(VirtualCircuitTermination)
  578. class VirtualCircuitTerminationView(generic.ObjectView):
  579. queryset = VirtualCircuitTermination.objects.all()
  580. @register_model_view(VirtualCircuitTermination, 'edit')
  581. class VirtualCircuitTerminationEditView(generic.ObjectEditView):
  582. queryset = VirtualCircuitTermination.objects.all()
  583. form = forms.VirtualCircuitTerminationForm
  584. @register_model_view(VirtualCircuitTermination, 'delete')
  585. class VirtualCircuitTerminationDeleteView(generic.ObjectDeleteView):
  586. queryset = VirtualCircuitTermination.objects.all()
  587. class VirtualCircuitTerminationBulkImportView(generic.BulkImportView):
  588. queryset = VirtualCircuitTermination.objects.all()
  589. model_form = forms.VirtualCircuitTerminationImportForm
  590. class VirtualCircuitTerminationBulkEditView(generic.BulkEditView):
  591. queryset = VirtualCircuitTermination.objects.all()
  592. filterset = filtersets.VirtualCircuitTerminationFilterSet
  593. table = tables.VirtualCircuitTerminationTable
  594. form = forms.VirtualCircuitTerminationBulkEditForm
  595. class VirtualCircuitTerminationBulkDeleteView(generic.BulkDeleteView):
  596. queryset = VirtualCircuitTermination.objects.all()
  597. filterset = filtersets.VirtualCircuitTerminationFilterSet
  598. table = tables.VirtualCircuitTerminationTable