bulk_edit.py 9.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335
  1. from django import forms
  2. from django.contrib.contenttypes.models import ContentType
  3. from django.core.exceptions import ObjectDoesNotExist
  4. from django.utils.translation import gettext_lazy as _
  5. from circuits.choices import (
  6. CircuitCommitRateChoices, CircuitPriorityChoices, CircuitStatusChoices, VirtualCircuitTerminationRoleChoices,
  7. )
  8. from circuits.constants import CIRCUIT_TERMINATION_TERMINATION_TYPES
  9. from circuits.models import *
  10. from dcim.models import Site
  11. from ipam.models import ASN
  12. from netbox.choices import DistanceUnitChoices
  13. from netbox.forms import NetBoxModelBulkEditForm, OrganizationalModelBulkEditForm, PrimaryModelBulkEditForm
  14. from tenancy.models import Tenant
  15. from utilities.forms import add_blank_choice, get_field_value
  16. from utilities.forms.fields import (
  17. ColorField, ContentTypeChoiceField, DynamicModelChoiceField, DynamicModelMultipleChoiceField,
  18. )
  19. from utilities.forms.rendering import FieldSet
  20. from utilities.forms.widgets import BulkEditNullBooleanSelect, DatePicker, HTMXSelect, NumberWithOptions
  21. from utilities.templatetags.builtins.filters import bettertitle
  22. __all__ = (
  23. 'CircuitBulkEditForm',
  24. 'CircuitGroupAssignmentBulkEditForm',
  25. 'CircuitGroupBulkEditForm',
  26. 'CircuitTerminationBulkEditForm',
  27. 'CircuitTypeBulkEditForm',
  28. 'ProviderBulkEditForm',
  29. 'ProviderAccountBulkEditForm',
  30. 'ProviderNetworkBulkEditForm',
  31. 'VirtualCircuitBulkEditForm',
  32. 'VirtualCircuitTerminationBulkEditForm',
  33. 'VirtualCircuitTypeBulkEditForm',
  34. )
  35. class ProviderBulkEditForm(PrimaryModelBulkEditForm):
  36. asns = DynamicModelMultipleChoiceField(
  37. queryset=ASN.objects.all(),
  38. label=_('ASNs'),
  39. required=False
  40. )
  41. model = Provider
  42. fieldsets = (
  43. FieldSet('asns', 'description'),
  44. )
  45. nullable_fields = (
  46. 'asns', 'description', 'comments',
  47. )
  48. class ProviderAccountBulkEditForm(PrimaryModelBulkEditForm):
  49. provider = DynamicModelChoiceField(
  50. label=_('Provider'),
  51. queryset=Provider.objects.all(),
  52. required=False
  53. )
  54. model = ProviderAccount
  55. fieldsets = (
  56. FieldSet('provider', 'description'),
  57. )
  58. nullable_fields = (
  59. 'description', 'comments',
  60. )
  61. class ProviderNetworkBulkEditForm(PrimaryModelBulkEditForm):
  62. provider = DynamicModelChoiceField(
  63. label=_('Provider'),
  64. queryset=Provider.objects.all(),
  65. required=False
  66. )
  67. service_id = forms.CharField(
  68. max_length=100,
  69. required=False,
  70. label=_('Service ID')
  71. )
  72. model = ProviderNetwork
  73. fieldsets = (
  74. FieldSet('provider', 'service_id', 'description'),
  75. )
  76. nullable_fields = (
  77. 'service_id', 'description', 'comments',
  78. )
  79. class CircuitTypeBulkEditForm(OrganizationalModelBulkEditForm):
  80. color = ColorField(
  81. label=_('Color'),
  82. required=False
  83. )
  84. model = CircuitType
  85. fieldsets = (
  86. FieldSet('color', 'description'),
  87. )
  88. nullable_fields = ('color', 'description', 'comments')
  89. class CircuitBulkEditForm(PrimaryModelBulkEditForm):
  90. type = DynamicModelChoiceField(
  91. label=_('Type'),
  92. queryset=CircuitType.objects.all(),
  93. required=False
  94. )
  95. provider = DynamicModelChoiceField(
  96. label=_('Provider'),
  97. queryset=Provider.objects.all(),
  98. required=False
  99. )
  100. provider_account = DynamicModelChoiceField(
  101. label=_('Provider account'),
  102. queryset=ProviderAccount.objects.all(),
  103. required=False,
  104. query_params={
  105. 'provider': '$provider'
  106. }
  107. )
  108. status = forms.ChoiceField(
  109. label=_('Status'),
  110. choices=add_blank_choice(CircuitStatusChoices),
  111. required=False,
  112. initial=''
  113. )
  114. tenant = DynamicModelChoiceField(
  115. label=_('Tenant'),
  116. queryset=Tenant.objects.all(),
  117. required=False
  118. )
  119. install_date = forms.DateField(
  120. label=_('Install date'),
  121. required=False,
  122. widget=DatePicker()
  123. )
  124. termination_date = forms.DateField(
  125. label=_('Termination date'),
  126. required=False,
  127. widget=DatePicker()
  128. )
  129. commit_rate = forms.IntegerField(
  130. required=False,
  131. label=_('Commit rate (Kbps)'),
  132. widget=NumberWithOptions(
  133. options=CircuitCommitRateChoices
  134. )
  135. )
  136. distance = forms.DecimalField(
  137. label=_('Distance'),
  138. min_value=0,
  139. required=False
  140. )
  141. distance_unit = forms.ChoiceField(
  142. label=_('Distance unit'),
  143. choices=add_blank_choice(DistanceUnitChoices),
  144. required=False,
  145. initial=''
  146. )
  147. model = Circuit
  148. fieldsets = (
  149. FieldSet('provider', 'type', 'status', 'description', name=_('Circuit')),
  150. FieldSet('provider_account', 'install_date', 'termination_date', 'commit_rate', name=_('Service Parameters')),
  151. FieldSet('distance', 'distance_unit', name=_('Attributes')),
  152. FieldSet('tenant', name=_('Tenancy')),
  153. )
  154. nullable_fields = (
  155. 'tenant', 'commit_rate', 'description', 'comments',
  156. )
  157. class CircuitTerminationBulkEditForm(NetBoxModelBulkEditForm):
  158. description = forms.CharField(
  159. label=_('Description'),
  160. max_length=200,
  161. required=False
  162. )
  163. termination_type = ContentTypeChoiceField(
  164. queryset=ContentType.objects.filter(model__in=CIRCUIT_TERMINATION_TERMINATION_TYPES),
  165. widget=HTMXSelect(method='post', attrs={'hx-select': '#form_fields'}),
  166. required=False,
  167. label=_('Termination type')
  168. )
  169. termination = DynamicModelChoiceField(
  170. label=_('Termination'),
  171. queryset=Site.objects.none(), # Initial queryset
  172. required=False,
  173. disabled=True,
  174. selector=True
  175. )
  176. port_speed = forms.IntegerField(
  177. required=False,
  178. label=_('Port speed (Kbps)'),
  179. )
  180. upstream_speed = forms.IntegerField(
  181. required=False,
  182. label=_('Upstream speed (Kbps)'),
  183. )
  184. mark_connected = forms.NullBooleanField(
  185. label=_('Mark connected'),
  186. required=False,
  187. widget=BulkEditNullBooleanSelect
  188. )
  189. model = CircuitTermination
  190. fieldsets = (
  191. FieldSet(
  192. 'description',
  193. 'termination_type', 'termination',
  194. 'mark_connected', name=_('Circuit Termination')
  195. ),
  196. FieldSet('port_speed', 'upstream_speed', name=_('Termination Details')),
  197. )
  198. nullable_fields = ('description', 'termination')
  199. def __init__(self, *args, **kwargs):
  200. super().__init__(*args, **kwargs)
  201. if termination_type_id := get_field_value(self, 'termination_type'):
  202. try:
  203. termination_type = ContentType.objects.get(pk=termination_type_id)
  204. model = termination_type.model_class()
  205. self.fields['termination'].queryset = model.objects.all()
  206. self.fields['termination'].widget.attrs['selector'] = model._meta.label_lower
  207. self.fields['termination'].disabled = False
  208. self.fields['termination'].label = _(bettertitle(model._meta.verbose_name))
  209. except ObjectDoesNotExist:
  210. pass
  211. class CircuitGroupBulkEditForm(OrganizationalModelBulkEditForm):
  212. tenant = DynamicModelChoiceField(
  213. label=_('Tenant'),
  214. queryset=Tenant.objects.all(),
  215. required=False
  216. )
  217. model = CircuitGroup
  218. nullable_fields = (
  219. 'description', 'tenant', 'comments',
  220. )
  221. class CircuitGroupAssignmentBulkEditForm(NetBoxModelBulkEditForm):
  222. member = DynamicModelChoiceField(
  223. label=_('Circuit'),
  224. queryset=Circuit.objects.all(),
  225. required=False
  226. )
  227. priority = forms.ChoiceField(
  228. label=_('Priority'),
  229. choices=add_blank_choice(CircuitPriorityChoices),
  230. required=False
  231. )
  232. model = CircuitGroupAssignment
  233. fieldsets = (
  234. FieldSet('member', 'priority'),
  235. )
  236. nullable_fields = ('priority',)
  237. class VirtualCircuitTypeBulkEditForm(OrganizationalModelBulkEditForm):
  238. color = ColorField(
  239. label=_('Color'),
  240. required=False
  241. )
  242. model = VirtualCircuitType
  243. fieldsets = (
  244. FieldSet('color', 'description'),
  245. )
  246. nullable_fields = ('color', 'description', 'comments')
  247. class VirtualCircuitBulkEditForm(PrimaryModelBulkEditForm):
  248. provider_network = DynamicModelChoiceField(
  249. label=_('Provider network'),
  250. queryset=ProviderNetwork.objects.all(),
  251. required=False
  252. )
  253. provider_account = DynamicModelChoiceField(
  254. label=_('Provider account'),
  255. queryset=ProviderAccount.objects.all(),
  256. required=False
  257. )
  258. type = DynamicModelChoiceField(
  259. label=_('Type'),
  260. queryset=VirtualCircuitType.objects.all(),
  261. required=False
  262. )
  263. status = forms.ChoiceField(
  264. label=_('Status'),
  265. choices=add_blank_choice(CircuitStatusChoices),
  266. required=False,
  267. initial=''
  268. )
  269. tenant = DynamicModelChoiceField(
  270. label=_('Tenant'),
  271. queryset=Tenant.objects.all(),
  272. required=False
  273. )
  274. model = VirtualCircuit
  275. fieldsets = (
  276. FieldSet('provider_network', 'provider_account', 'status', 'description', name=_('Virtual circuit')),
  277. FieldSet('tenant', name=_('Tenancy')),
  278. )
  279. nullable_fields = (
  280. 'provider_account', 'tenant', 'description', 'comments',
  281. )
  282. class VirtualCircuitTerminationBulkEditForm(NetBoxModelBulkEditForm):
  283. role = forms.ChoiceField(
  284. label=_('Role'),
  285. choices=add_blank_choice(VirtualCircuitTerminationRoleChoices),
  286. required=False,
  287. initial=''
  288. )
  289. description = forms.CharField(
  290. label=_('Description'),
  291. max_length=200,
  292. required=False
  293. )
  294. model = VirtualCircuitTermination
  295. fieldsets = (
  296. FieldSet('role', 'description'),
  297. )
  298. nullable_fields = ('description',)