forms.py 9.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353
  1. from django import forms
  2. from taggit.forms import TagField
  3. from dcim.models import Region, Site
  4. from extras.forms import (
  5. AddRemoveTagsForm, CustomFieldBulkEditForm, CustomFieldFilterForm, CustomFieldModelForm, CustomFieldModelCSVForm,
  6. )
  7. from tenancy.forms import TenancyFilterForm, TenancyForm
  8. from tenancy.models import Tenant
  9. from utilities.forms import (
  10. APISelect, APISelectMultiple, add_blank_choice, BootstrapMixin, CommentField, CSVChoiceField, DatePicker,
  11. DynamicModelChoiceField, DynamicModelMultipleChoiceField, SmallTextarea, SlugField, StaticSelect2,
  12. StaticSelect2Multiple, TagFilterField,
  13. )
  14. from .choices import CircuitStatusChoices
  15. from .models import Circuit, CircuitTermination, CircuitType, Provider
  16. #
  17. # Providers
  18. #
  19. class ProviderForm(BootstrapMixin, CustomFieldModelForm):
  20. slug = SlugField()
  21. comments = CommentField()
  22. tags = TagField(
  23. required=False
  24. )
  25. class Meta:
  26. model = Provider
  27. fields = [
  28. 'name', 'slug', 'asn', 'account', 'portal_url', 'noc_contact', 'admin_contact', 'comments', 'tags',
  29. ]
  30. widgets = {
  31. 'noc_contact': SmallTextarea(
  32. attrs={'rows': 5}
  33. ),
  34. 'admin_contact': SmallTextarea(
  35. attrs={'rows': 5}
  36. ),
  37. }
  38. help_texts = {
  39. 'name': "Full name of the provider",
  40. 'asn': "BGP autonomous system number (if applicable)",
  41. 'portal_url': "URL of the provider's customer support portal",
  42. 'noc_contact': "NOC email address and phone number",
  43. 'admin_contact': "Administrative contact email address and phone number",
  44. }
  45. class ProviderCSVForm(CustomFieldModelCSVForm):
  46. slug = SlugField()
  47. class Meta:
  48. model = Provider
  49. fields = Provider.csv_headers
  50. help_texts = {
  51. 'name': 'Provider name',
  52. 'asn': '32-bit autonomous system number',
  53. 'portal_url': 'Portal URL',
  54. 'comments': 'Free-form comments',
  55. }
  56. class ProviderBulkEditForm(BootstrapMixin, AddRemoveTagsForm, CustomFieldBulkEditForm):
  57. pk = forms.ModelMultipleChoiceField(
  58. queryset=Provider.objects.all(),
  59. widget=forms.MultipleHiddenInput
  60. )
  61. asn = forms.IntegerField(
  62. required=False,
  63. label='ASN'
  64. )
  65. account = forms.CharField(
  66. max_length=30,
  67. required=False,
  68. label='Account number'
  69. )
  70. portal_url = forms.URLField(
  71. required=False,
  72. label='Portal'
  73. )
  74. noc_contact = forms.CharField(
  75. required=False,
  76. widget=SmallTextarea,
  77. label='NOC contact'
  78. )
  79. admin_contact = forms.CharField(
  80. required=False,
  81. widget=SmallTextarea,
  82. label='Admin contact'
  83. )
  84. comments = CommentField(
  85. widget=SmallTextarea,
  86. label='Comments'
  87. )
  88. class Meta:
  89. nullable_fields = [
  90. 'asn', 'account', 'portal_url', 'noc_contact', 'admin_contact', 'comments',
  91. ]
  92. class ProviderFilterForm(BootstrapMixin, CustomFieldFilterForm):
  93. model = Provider
  94. q = forms.CharField(
  95. required=False,
  96. label='Search'
  97. )
  98. region = DynamicModelMultipleChoiceField(
  99. queryset=Region.objects.all(),
  100. to_field_name='slug',
  101. required=False,
  102. widget=APISelectMultiple(
  103. value_field="slug",
  104. filter_for={
  105. 'site': 'region'
  106. }
  107. )
  108. )
  109. site = DynamicModelMultipleChoiceField(
  110. queryset=Site.objects.all(),
  111. to_field_name='slug',
  112. required=False,
  113. widget=APISelectMultiple(
  114. value_field="slug",
  115. )
  116. )
  117. asn = forms.IntegerField(
  118. required=False,
  119. label='ASN'
  120. )
  121. tag = TagFilterField(model)
  122. #
  123. # Circuit types
  124. #
  125. class CircuitTypeForm(BootstrapMixin, forms.ModelForm):
  126. slug = SlugField()
  127. class Meta:
  128. model = CircuitType
  129. fields = [
  130. 'name', 'slug', 'description',
  131. ]
  132. class CircuitTypeCSVForm(forms.ModelForm):
  133. slug = SlugField()
  134. class Meta:
  135. model = CircuitType
  136. fields = CircuitType.csv_headers
  137. help_texts = {
  138. 'name': 'Name of circuit type',
  139. }
  140. #
  141. # Circuits
  142. #
  143. class CircuitForm(BootstrapMixin, TenancyForm, CustomFieldModelForm):
  144. provider = DynamicModelChoiceField(
  145. queryset=Provider.objects.all()
  146. )
  147. type = DynamicModelChoiceField(
  148. queryset=CircuitType.objects.all()
  149. )
  150. comments = CommentField()
  151. tags = TagField(
  152. required=False
  153. )
  154. class Meta:
  155. model = Circuit
  156. fields = [
  157. 'cid', 'type', 'provider', 'status', 'install_date', 'commit_rate', 'description', 'tenant_group', 'tenant',
  158. 'comments', 'tags',
  159. ]
  160. help_texts = {
  161. 'cid': "Unique circuit ID",
  162. 'commit_rate': "Committed rate",
  163. }
  164. widgets = {
  165. 'status': StaticSelect2(),
  166. 'install_date': DatePicker(),
  167. }
  168. class CircuitCSVForm(CustomFieldModelCSVForm):
  169. provider = forms.ModelChoiceField(
  170. queryset=Provider.objects.all(),
  171. to_field_name='name',
  172. help_text='Name of parent provider',
  173. error_messages={
  174. 'invalid_choice': 'Provider not found.'
  175. }
  176. )
  177. type = forms.ModelChoiceField(
  178. queryset=CircuitType.objects.all(),
  179. to_field_name='name',
  180. help_text='Type of circuit',
  181. error_messages={
  182. 'invalid_choice': 'Invalid circuit type.'
  183. }
  184. )
  185. status = CSVChoiceField(
  186. choices=CircuitStatusChoices,
  187. required=False,
  188. help_text='Operational status'
  189. )
  190. tenant = forms.ModelChoiceField(
  191. queryset=Tenant.objects.all(),
  192. required=False,
  193. to_field_name='name',
  194. help_text='Name of assigned tenant',
  195. error_messages={
  196. 'invalid_choice': 'Tenant not found.'
  197. }
  198. )
  199. class Meta:
  200. model = Circuit
  201. fields = [
  202. 'cid', 'provider', 'type', 'status', 'tenant', 'install_date', 'commit_rate', 'description', 'comments',
  203. ]
  204. class CircuitBulkEditForm(BootstrapMixin, AddRemoveTagsForm, CustomFieldBulkEditForm):
  205. pk = forms.ModelMultipleChoiceField(
  206. queryset=Circuit.objects.all(),
  207. widget=forms.MultipleHiddenInput
  208. )
  209. type = DynamicModelChoiceField(
  210. queryset=CircuitType.objects.all(),
  211. required=False
  212. )
  213. provider = DynamicModelChoiceField(
  214. queryset=Provider.objects.all(),
  215. required=False
  216. )
  217. status = forms.ChoiceField(
  218. choices=add_blank_choice(CircuitStatusChoices),
  219. required=False,
  220. initial='',
  221. widget=StaticSelect2()
  222. )
  223. tenant = DynamicModelChoiceField(
  224. queryset=Tenant.objects.all(),
  225. required=False
  226. )
  227. commit_rate = forms.IntegerField(
  228. required=False,
  229. label='Commit rate (Kbps)'
  230. )
  231. description = forms.CharField(
  232. max_length=100,
  233. required=False
  234. )
  235. comments = CommentField(
  236. widget=SmallTextarea,
  237. label='Comments'
  238. )
  239. class Meta:
  240. nullable_fields = [
  241. 'tenant', 'commit_rate', 'description', 'comments',
  242. ]
  243. class CircuitFilterForm(BootstrapMixin, TenancyFilterForm, CustomFieldFilterForm):
  244. model = Circuit
  245. field_order = [
  246. 'q', 'type', 'provider', 'status', 'region', 'site', 'tenant_group', 'tenant', 'commit_rate',
  247. ]
  248. q = forms.CharField(
  249. required=False,
  250. label='Search'
  251. )
  252. type = DynamicModelMultipleChoiceField(
  253. queryset=CircuitType.objects.all(),
  254. to_field_name='slug',
  255. required=False,
  256. widget=APISelectMultiple(
  257. value_field="slug",
  258. )
  259. )
  260. provider = DynamicModelMultipleChoiceField(
  261. queryset=Provider.objects.all(),
  262. to_field_name='slug',
  263. required=False,
  264. widget=APISelectMultiple(
  265. value_field="slug",
  266. )
  267. )
  268. status = forms.MultipleChoiceField(
  269. choices=CircuitStatusChoices,
  270. required=False,
  271. widget=StaticSelect2Multiple()
  272. )
  273. region = DynamicModelMultipleChoiceField(
  274. queryset=Region.objects.all(),
  275. to_field_name='slug',
  276. required=False,
  277. widget=APISelectMultiple(
  278. value_field="slug",
  279. filter_for={
  280. 'site': 'region'
  281. }
  282. )
  283. )
  284. site = DynamicModelMultipleChoiceField(
  285. queryset=Site.objects.all(),
  286. to_field_name='slug',
  287. required=False,
  288. widget=APISelectMultiple(
  289. value_field="slug",
  290. )
  291. )
  292. commit_rate = forms.IntegerField(
  293. required=False,
  294. min_value=0,
  295. label='Commit rate (Kbps)'
  296. )
  297. tag = TagFilterField(model)
  298. #
  299. # Circuit terminations
  300. #
  301. class CircuitTerminationForm(BootstrapMixin, forms.ModelForm):
  302. site = DynamicModelChoiceField(
  303. queryset=Site.objects.all()
  304. )
  305. class Meta:
  306. model = CircuitTermination
  307. fields = [
  308. 'term_side', 'site', 'port_speed', 'upstream_speed', 'xconnect_id', 'pp_info', 'description',
  309. ]
  310. help_texts = {
  311. 'port_speed': "Physical circuit speed",
  312. 'xconnect_id': "ID of the local cross-connect",
  313. 'pp_info': "Patch panel ID and port number(s)"
  314. }
  315. widgets = {
  316. 'term_side': forms.HiddenInput(),
  317. }