model_forms.py 8.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252
  1. from django import forms
  2. from django.contrib.contenttypes.models import ContentType
  3. from dcim.models import DeviceRole, DeviceType, Location, Platform, Region, Site, SiteGroup
  4. from extras.choices import *
  5. from extras.models import *
  6. from extras.utils import FeatureQuery
  7. from netbox.forms import NetBoxModelForm
  8. from tenancy.models import Tenant, TenantGroup
  9. from utilities.forms import (
  10. add_blank_choice, BootstrapMixin, CommentField, ContentTypeChoiceField, ContentTypeMultipleChoiceField,
  11. DynamicModelMultipleChoiceField, JSONField, SlugField, StaticSelect,
  12. )
  13. from virtualization.models import Cluster, ClusterGroup, ClusterType
  14. __all__ = (
  15. 'ConfigContextForm',
  16. 'CustomFieldForm',
  17. 'CustomLinkForm',
  18. 'ExportTemplateForm',
  19. 'ImageAttachmentForm',
  20. 'JournalEntryForm',
  21. 'TagForm',
  22. 'WebhookForm',
  23. )
  24. class CustomFieldForm(BootstrapMixin, forms.ModelForm):
  25. content_types = ContentTypeMultipleChoiceField(
  26. queryset=ContentType.objects.all(),
  27. limit_choices_to=FeatureQuery('custom_fields'),
  28. label='Model(s)'
  29. )
  30. object_type = ContentTypeChoiceField(
  31. queryset=ContentType.objects.all(),
  32. # TODO: Come up with a canonical way to register suitable models
  33. limit_choices_to=FeatureQuery('webhooks'),
  34. required=False,
  35. help_text="Type of the related object (for object/multi-object fields only)"
  36. )
  37. fieldsets = (
  38. ('Custom Field', (
  39. 'content_types', 'name', 'label', 'group_name', 'type', 'object_type', 'required', 'description',
  40. )),
  41. ('Behavior', ('search_weight', 'filter_logic', 'ui_visibility', 'weight')),
  42. ('Values', ('default', 'choices')),
  43. ('Validation', ('validation_minimum', 'validation_maximum', 'validation_regex')),
  44. )
  45. class Meta:
  46. model = CustomField
  47. fields = '__all__'
  48. help_texts = {
  49. 'type': "The type of data stored in this field. For object/multi-object fields, select the related object "
  50. "type below."
  51. }
  52. widgets = {
  53. 'type': StaticSelect(),
  54. 'filter_logic': StaticSelect(),
  55. 'ui_visibility': StaticSelect(),
  56. }
  57. class CustomLinkForm(BootstrapMixin, forms.ModelForm):
  58. content_types = ContentTypeMultipleChoiceField(
  59. queryset=ContentType.objects.all(),
  60. limit_choices_to=FeatureQuery('custom_links')
  61. )
  62. fieldsets = (
  63. ('Custom Link', ('name', 'content_types', 'weight', 'group_name', 'button_class', 'enabled', 'new_window')),
  64. ('Templates', ('link_text', 'link_url')),
  65. )
  66. class Meta:
  67. model = CustomLink
  68. fields = '__all__'
  69. widgets = {
  70. 'button_class': StaticSelect(),
  71. 'link_text': forms.Textarea(attrs={'class': 'font-monospace'}),
  72. 'link_url': forms.Textarea(attrs={'class': 'font-monospace'}),
  73. }
  74. help_texts = {
  75. 'link_text': 'Jinja2 template code for the link text. Reference the object as <code>{{ object }}</code>. '
  76. 'Links which render as empty text will not be displayed.',
  77. 'link_url': 'Jinja2 template code for the link URL. Reference the object as <code>{{ object }}</code>.',
  78. }
  79. class ExportTemplateForm(BootstrapMixin, forms.ModelForm):
  80. content_types = ContentTypeMultipleChoiceField(
  81. queryset=ContentType.objects.all(),
  82. limit_choices_to=FeatureQuery('export_templates')
  83. )
  84. fieldsets = (
  85. ('Export Template', ('name', 'content_types', 'description')),
  86. ('Template', ('template_code',)),
  87. ('Rendering', ('mime_type', 'file_extension', 'as_attachment')),
  88. )
  89. class Meta:
  90. model = ExportTemplate
  91. fields = '__all__'
  92. widgets = {
  93. 'template_code': forms.Textarea(attrs={'class': 'font-monospace'}),
  94. }
  95. class WebhookForm(BootstrapMixin, forms.ModelForm):
  96. content_types = ContentTypeMultipleChoiceField(
  97. queryset=ContentType.objects.all(),
  98. limit_choices_to=FeatureQuery('webhooks')
  99. )
  100. fieldsets = (
  101. ('Webhook', ('name', 'content_types', 'enabled')),
  102. ('Events', ('type_create', 'type_update', 'type_delete')),
  103. ('HTTP Request', (
  104. 'payload_url', 'http_method', 'http_content_type', 'additional_headers', 'body_template', 'secret',
  105. )),
  106. ('Conditions', ('conditions',)),
  107. ('SSL', ('ssl_verification', 'ca_file_path')),
  108. )
  109. class Meta:
  110. model = Webhook
  111. fields = '__all__'
  112. labels = {
  113. 'type_create': 'Creations',
  114. 'type_update': 'Updates',
  115. 'type_delete': 'Deletions',
  116. }
  117. widgets = {
  118. 'http_method': StaticSelect(),
  119. 'additional_headers': forms.Textarea(attrs={'class': 'font-monospace'}),
  120. 'body_template': forms.Textarea(attrs={'class': 'font-monospace'}),
  121. 'conditions': forms.Textarea(attrs={'class': 'font-monospace'}),
  122. }
  123. class TagForm(BootstrapMixin, forms.ModelForm):
  124. slug = SlugField()
  125. fieldsets = (
  126. ('Tag', ('name', 'slug', 'color', 'description')),
  127. )
  128. class Meta:
  129. model = Tag
  130. fields = [
  131. 'name', 'slug', 'color', 'description'
  132. ]
  133. class ConfigContextForm(BootstrapMixin, forms.ModelForm):
  134. regions = DynamicModelMultipleChoiceField(
  135. queryset=Region.objects.all(),
  136. required=False
  137. )
  138. site_groups = DynamicModelMultipleChoiceField(
  139. queryset=SiteGroup.objects.all(),
  140. required=False
  141. )
  142. sites = DynamicModelMultipleChoiceField(
  143. queryset=Site.objects.all(),
  144. required=False
  145. )
  146. locations = DynamicModelMultipleChoiceField(
  147. queryset=Location.objects.all(),
  148. required=False
  149. )
  150. device_types = DynamicModelMultipleChoiceField(
  151. queryset=DeviceType.objects.all(),
  152. required=False
  153. )
  154. roles = DynamicModelMultipleChoiceField(
  155. queryset=DeviceRole.objects.all(),
  156. required=False
  157. )
  158. platforms = DynamicModelMultipleChoiceField(
  159. queryset=Platform.objects.all(),
  160. required=False
  161. )
  162. cluster_types = DynamicModelMultipleChoiceField(
  163. queryset=ClusterType.objects.all(),
  164. required=False
  165. )
  166. cluster_groups = DynamicModelMultipleChoiceField(
  167. queryset=ClusterGroup.objects.all(),
  168. required=False
  169. )
  170. clusters = DynamicModelMultipleChoiceField(
  171. queryset=Cluster.objects.all(),
  172. required=False
  173. )
  174. tenant_groups = DynamicModelMultipleChoiceField(
  175. queryset=TenantGroup.objects.all(),
  176. required=False
  177. )
  178. tenants = DynamicModelMultipleChoiceField(
  179. queryset=Tenant.objects.all(),
  180. required=False
  181. )
  182. tags = DynamicModelMultipleChoiceField(
  183. queryset=Tag.objects.all(),
  184. required=False
  185. )
  186. data = JSONField()
  187. fieldsets = (
  188. ('Config Context', ('name', 'weight', 'description', 'data', 'is_active')),
  189. ('Assignment', (
  190. 'regions', 'site_groups', 'sites', 'locations', 'device_types', 'roles', 'platforms', 'cluster_types',
  191. 'cluster_groups', 'clusters', 'tenant_groups', 'tenants', 'tags',
  192. )),
  193. )
  194. class Meta:
  195. model = ConfigContext
  196. fields = (
  197. 'name', 'weight', 'description', 'data', 'is_active', 'regions', 'site_groups', 'sites', 'locations',
  198. 'roles', 'device_types', 'platforms', 'cluster_types', 'cluster_groups', 'clusters', 'tenant_groups',
  199. 'tenants', 'tags',
  200. )
  201. class ImageAttachmentForm(BootstrapMixin, forms.ModelForm):
  202. class Meta:
  203. model = ImageAttachment
  204. fields = [
  205. 'name', 'image',
  206. ]
  207. class JournalEntryForm(NetBoxModelForm):
  208. kind = forms.ChoiceField(
  209. choices=add_blank_choice(JournalEntryKindChoices),
  210. required=False,
  211. widget=StaticSelect()
  212. )
  213. comments = CommentField()
  214. class Meta:
  215. model = JournalEntry
  216. fields = ['assigned_object_type', 'assigned_object_id', 'kind', 'tags', 'comments']
  217. widgets = {
  218. 'assigned_object_type': forms.HiddenInput,
  219. 'assigned_object_id': forms.HiddenInput,
  220. }