From f93702f0a19c9a2cc7bff0d99edf8488049af582 Mon Sep 17 00:00:00 2001 From: Arthur Date: Tue, 13 Jun 2023 16:14:40 -0700 Subject: [PATCH] 12591 add/edit view --- netbox/extras/forms/model_forms.py | 76 ++++++++++++++++++++++++++++++ netbox/extras/urls.py | 2 +- netbox/extras/views.py | 7 +++ 3 files changed, 84 insertions(+), 1 deletion(-) diff --git a/netbox/extras/forms/model_forms.py b/netbox/extras/forms/model_forms.py index 2f617b682..aaa426ac3 100644 --- a/netbox/extras/forms/model_forms.py +++ b/netbox/extras/forms/model_forms.py @@ -10,6 +10,7 @@ from dcim.models import DeviceRole, DeviceType, Location, Platform, Region, Site from extras.choices import * from extras.models import * from extras.utils import FeatureQuery +from netbox.config import get_config, PARAMS from netbox.forms import NetBoxModelForm from tenancy.models import Tenant, TenantGroup from utilities.forms import BootstrapMixin, add_blank_choice @@ -21,6 +22,7 @@ from virtualization.models import Cluster, ClusterGroup, ClusterType __all__ = ( 'ConfigContextForm', + 'ConfigRevisionForm', 'ConfigTemplateForm', 'CustomFieldForm', 'CustomLinkForm', @@ -374,3 +376,77 @@ class JournalEntryForm(NetBoxModelForm): 'assigned_object_type': forms.HiddenInput, 'assigned_object_id': forms.HiddenInput, } + + +EMPTY_VALUES = ('', None, [], ()) + + +class FormMetaclass(forms.models.ModelFormMetaclass): + + def __new__(mcs, name, bases, attrs): + + # Emulate a declared field for each supported configuration parameter + param_fields = {} + for param in PARAMS: + field_kwargs = { + 'required': False, + 'label': param.label, + 'help_text': param.description, + } + field_kwargs.update(**param.field_kwargs) + param_fields[param.name] = param.field(**field_kwargs) + attrs.update(param_fields) + + return super().__new__(mcs, name, bases, attrs) + + +class ConfigRevisionForm(forms.BaseModelForm, metaclass=FormMetaclass): + """ + Form for creating a new ConfigRevision. + """ + class Meta: + widgets = { + 'comment': forms.Textarea(), + } + + def __init__(self, *args, **kwargs): + super().__init__(*args, **kwargs) + + # Append current parameter values to form field help texts and check for static configurations + config = get_config() + for param in PARAMS: + value = getattr(config, param.name) + is_static = hasattr(settings, param.name) + if value: + help_text = self.fields[param.name].help_text + if help_text: + help_text += '
' # Line break + help_text += f'Current value: {value}' + if is_static: + help_text += ' (defined statically)' + elif value == param.default: + help_text += ' (default)' + self.fields[param.name].help_text = help_text + if is_static: + self.fields[param.name].disabled = True + + def save(self, commit=True): + instance = super().save(commit=False) + + # Populate JSON data on the instance + instance.data = self.render_json() + + if commit: + instance.save() + + return instance + + def render_json(self): + json = {} + + # Iterate through each field and populate non-empty values + for field_name in self.declared_fields: + if field_name in self.cleaned_data and self.cleaned_data[field_name] not in EMPTY_VALUES: + json[field_name] = self.cleaned_data[field_name] + + return json diff --git a/netbox/extras/urls.py b/netbox/extras/urls.py index 811576b3c..13f8fdf28 100644 --- a/netbox/extras/urls.py +++ b/netbox/extras/urls.py @@ -118,5 +118,5 @@ urlpatterns = [ # Config Revision path('config-revision/', views.ConfigRevisionView.as_view(), name='config_revision'), - + path('config-revision/add/', views.ConfigRevisionEditView.as_view(), name='config_revision_add'), ] diff --git a/netbox/extras/views.py b/netbox/extras/views.py index 81bea84f1..842936766 100644 --- a/netbox/extras/views.py +++ b/netbox/extras/views.py @@ -1195,6 +1195,7 @@ class RenderMarkdownView(View): # Config Revision # +@register_model_view(ConfigRevision) class ConfigRevisionView(generic.ObjectView): queryset = ConfigRevision.objects.all() @@ -1206,3 +1207,9 @@ class ConfigRevisionView(generic.ObjectView): 'tab': self.tab, **self.get_extra_context(request, instance), }) + + +@register_model_view(ConfigRevision, 'edit') +class ConfigRevisionEditView(generic.ObjectEditView): + queryset = ConfigRevision.objects.all() + form = forms.ConfigRevisionForm