From 81707a18b37a0e3b5461407f30d9366d4b04afcc Mon Sep 17 00:00:00 2001 From: Idris FOUGHALI Date: Fri, 31 Oct 2025 14:36:40 +0100 Subject: [PATCH 01/17] Feat: added data_source & data_file fields for ConfigTemplate import form --- netbox/extras/forms/bulk_import.py | 45 ++++++++++++++++++++++++++++-- 1 file changed, 42 insertions(+), 3 deletions(-) diff --git a/netbox/extras/forms/bulk_import.py b/netbox/extras/forms/bulk_import.py index 4f7c85e8581..51d9de6ed74 100644 --- a/netbox/extras/forms/bulk_import.py +++ b/netbox/extras/forms/bulk_import.py @@ -4,7 +4,6 @@ from django.contrib.postgres.forms import SimpleArrayField from django.core.exceptions import ObjectDoesNotExist from django.utils.translation import gettext_lazy as _ - from core.models import ObjectType from extras.choices import * from extras.models import * @@ -14,8 +13,9 @@ from utilities.forms import CSVModelForm from utilities.forms.fields import ( CSVChoiceField, CSVContentTypeField, CSVModelChoiceField, CSVModelMultipleChoiceField, CSVMultipleChoiceField, - CSVMultipleContentTypeField, SlugField, + CSVMultipleContentTypeField, SlugField, DynamicModelMultipleChoiceField ) +from core.models import DataSource, DataFile __all__ = ( 'ConfigContextProfileImportForm', @@ -160,14 +160,53 @@ class Meta: class ConfigTemplateImportForm(CSVModelForm): + data_source = CSVModelChoiceField( + label=_('DataSource'), + queryset=DataSource.objects.all(), + required=False, + to_field_name='name', + help_text=_('data_source of the config template') + ) + + data_file = CSVModelChoiceField( + label=_('DataFile'), + queryset=DataFile.objects.all(), + required=False, + to_field_name='path', + help_text=_('DataFile containing the template code') + ) + + template_code = forms.CharField( + label=_('Template code'), + required=False, + widget=forms.Textarea(attrs={'class': 'font-monospace'}) + ) + + auto_sync_enabled = forms.BooleanField( + required=False, + label=_('auto sync enabled'), + help_text=_("Enable automatic synchronization of data when the data file is updated") + ) class Meta: model = ConfigTemplate fields = ( - 'name', 'description', 'template_code', 'environment_params', 'mime_type', 'file_name', 'file_extension', + 'name', 'description', 'template_code', 'data_source', 'data_file', 'auto_sync_enabled', 'environment_params', 'mime_type', 'file_name', 'file_extension', 'as_attachment', 'tags', ) + def clean_template_code(self): + # Make sure template_code is None when it's not included in the uploaded data + if not self.data.get('template_code') and not self.data.get('data_file'): + raise forms.ValidationError(_("Must specify either local content or a data file")) + + return self.cleaned_data['template_code'] + + def clean_auto_sync_enabled(self): + # Make sure is_primary is None when it's not included in the uploaded data + if not self.data.get('auto_sync_enabled'): + self.cleaned_data['auto_sync_enabled'] = False + return self.cleaned_data['auto_sync_enabled'] class SavedFilterImportForm(CSVModelForm): object_types = CSVMultipleContentTypeField( From 0340b804e6d9ca748226c49115c5acd81d71e281 Mon Sep 17 00:00:00 2001 From: ifoughali Date: Wed, 12 Nov 2025 14:21:38 +0100 Subject: [PATCH 02/17] Style: fixed linter issues --- netbox/extras/forms/bulk_import.py | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/netbox/extras/forms/bulk_import.py b/netbox/extras/forms/bulk_import.py index 51d9de6ed74..0d8628d511d 100644 --- a/netbox/extras/forms/bulk_import.py +++ b/netbox/extras/forms/bulk_import.py @@ -13,7 +13,7 @@ from utilities.forms import CSVModelForm from utilities.forms.fields import ( CSVChoiceField, CSVContentTypeField, CSVModelChoiceField, CSVModelMultipleChoiceField, CSVMultipleChoiceField, - CSVMultipleContentTypeField, SlugField, DynamicModelMultipleChoiceField + CSVMultipleContentTypeField, SlugField ) from core.models import DataSource, DataFile @@ -145,7 +145,8 @@ class ExportTemplateImportForm(CSVModelForm): class Meta: model = ExportTemplate fields = ( - 'name', 'object_types', 'description', 'environment_params', 'mime_type', 'file_name', 'file_extension', + 'name', 'object_types', 'description', 'environment_params', + 'mime_type', 'file_name', 'file_extension', 'as_attachment', 'template_code', ) @@ -191,8 +192,9 @@ class ConfigTemplateImportForm(CSVModelForm): class Meta: model = ConfigTemplate fields = ( - 'name', 'description', 'template_code', 'data_source', 'data_file', 'auto_sync_enabled', 'environment_params', 'mime_type', 'file_name', 'file_extension', - 'as_attachment', 'tags', + 'name', 'description', 'template_code', 'data_source', 'data_file', + 'auto_sync_enabled', 'environment_params', 'mime_type', 'file_name', + 'file_extension', 'as_attachment', 'tags', ) def clean_template_code(self): @@ -208,6 +210,7 @@ def clean_auto_sync_enabled(self): self.cleaned_data['auto_sync_enabled'] = False return self.cleaned_data['auto_sync_enabled'] + class SavedFilterImportForm(CSVModelForm): object_types = CSVMultipleContentTypeField( label=_('Object types'), From 6e92fc0b239be0c705b893dfc9b8716672bb7447 Mon Sep 17 00:00:00 2001 From: Idris Foughali Date: Thu, 13 Nov 2025 06:42:00 +0000 Subject: [PATCH 03/17] revert: Restore blank line between import groups in bulk_import.py --- netbox/extras/forms/bulk_import.py | 1 + 1 file changed, 1 insertion(+) diff --git a/netbox/extras/forms/bulk_import.py b/netbox/extras/forms/bulk_import.py index fa9669d1ebc..8389ad79545 100644 --- a/netbox/extras/forms/bulk_import.py +++ b/netbox/extras/forms/bulk_import.py @@ -4,6 +4,7 @@ from django.contrib.postgres.forms import SimpleArrayField from django.core.exceptions import ObjectDoesNotExist from django.utils.translation import gettext_lazy as _ + from core.models import ObjectType from extras.choices import * from extras.models import * From 1662a4f134fae749a13fdf985e4c11d0575e9d14 Mon Sep 17 00:00:00 2001 From: Idris Foughali Date: Thu, 13 Nov 2025 06:43:53 +0000 Subject: [PATCH 04/17] revert: Restored comma in grouped import --- netbox/extras/forms/bulk_import.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/netbox/extras/forms/bulk_import.py b/netbox/extras/forms/bulk_import.py index 8389ad79545..b09952754cc 100644 --- a/netbox/extras/forms/bulk_import.py +++ b/netbox/extras/forms/bulk_import.py @@ -14,7 +14,7 @@ from utilities.forms import CSVModelForm from utilities.forms.fields import ( CSVChoiceField, CSVContentTypeField, CSVModelChoiceField, CSVModelMultipleChoiceField, CSVMultipleChoiceField, - CSVMultipleContentTypeField, SlugField + CSVMultipleContentTypeField, SlugField, ) from core.models import DataSource, DataFile From da34c60bff68a12e5f5c561b2e274aa33b9b28bc Mon Sep 17 00:00:00 2001 From: Idris Foughali Date: Thu, 13 Nov 2025 06:47:31 +0000 Subject: [PATCH 05/17] Feat: combined core.models imports --- netbox/extras/forms/bulk_import.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/netbox/extras/forms/bulk_import.py b/netbox/extras/forms/bulk_import.py index b09952754cc..2f8ce4ac795 100644 --- a/netbox/extras/forms/bulk_import.py +++ b/netbox/extras/forms/bulk_import.py @@ -5,7 +5,7 @@ from django.core.exceptions import ObjectDoesNotExist from django.utils.translation import gettext_lazy as _ -from core.models import ObjectType +from core.models import ObjectType, DataSource, DataFile from extras.choices import * from extras.models import * from netbox.events import get_event_type_choices @@ -16,7 +16,6 @@ CSVChoiceField, CSVContentTypeField, CSVModelChoiceField, CSVModelMultipleChoiceField, CSVMultipleChoiceField, CSVMultipleContentTypeField, SlugField, ) -from core.models import DataSource, DataFile __all__ = ( 'ConfigContextProfileImportForm', From 0823015e3afadfccfc9df9cabeebe29b3b9f5ddf Mon Sep 17 00:00:00 2001 From: Idris Foughali Date: Thu, 13 Nov 2025 06:49:45 +0000 Subject: [PATCH 06/17] Revert: not in FR scope --- netbox/extras/forms/bulk_import.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/netbox/extras/forms/bulk_import.py b/netbox/extras/forms/bulk_import.py index 2f8ce4ac795..944ed70ca72 100644 --- a/netbox/extras/forms/bulk_import.py +++ b/netbox/extras/forms/bulk_import.py @@ -145,8 +145,7 @@ class ExportTemplateImportForm(CSVModelForm): class Meta: model = ExportTemplate fields = ( - 'name', 'object_types', 'description', 'environment_params', - 'mime_type', 'file_name', 'file_extension', + 'name', 'object_types', 'description', 'environment_params', 'mime_type', 'file_name', 'file_extension', 'as_attachment', 'template_code', ) From e0c012a05d1af22575e4660526109dc931da7ff9 Mon Sep 17 00:00:00 2001 From: Idris Foughali Date: Thu, 13 Nov 2025 06:51:02 +0000 Subject: [PATCH 07/17] Feat: renamed label to human-friendly --- netbox/extras/forms/bulk_import.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/netbox/extras/forms/bulk_import.py b/netbox/extras/forms/bulk_import.py index 944ed70ca72..1addfe083d4 100644 --- a/netbox/extras/forms/bulk_import.py +++ b/netbox/extras/forms/bulk_import.py @@ -161,7 +161,7 @@ class Meta: class ConfigTemplateImportForm(CSVModelForm): data_source = CSVModelChoiceField( - label=_('DataSource'), + label=_('Data source'), queryset=DataSource.objects.all(), required=False, to_field_name='name', From dc61f597c04908bf3e6b191c079434e16da2c439 Mon Sep 17 00:00:00 2001 From: Idris Foughali Date: Thu, 13 Nov 2025 06:52:09 +0000 Subject: [PATCH 08/17] Feat: enhanced helper text --- netbox/extras/forms/bulk_import.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/netbox/extras/forms/bulk_import.py b/netbox/extras/forms/bulk_import.py index 1addfe083d4..0d014c23ccf 100644 --- a/netbox/extras/forms/bulk_import.py +++ b/netbox/extras/forms/bulk_import.py @@ -165,7 +165,7 @@ class ConfigTemplateImportForm(CSVModelForm): queryset=DataSource.objects.all(), required=False, to_field_name='name', - help_text=_('data_source of the config template') + help_text=_('Data source which provides the data file') ) data_file = CSVModelChoiceField( From 6f31188b9dec30158b07720fa960492806181a17 Mon Sep 17 00:00:00 2001 From: Idris Foughali Date: Thu, 13 Nov 2025 06:53:55 +0000 Subject: [PATCH 09/17] Style: removed blank lines between attributes --- netbox/extras/forms/bulk_import.py | 3 --- 1 file changed, 3 deletions(-) diff --git a/netbox/extras/forms/bulk_import.py b/netbox/extras/forms/bulk_import.py index 0d014c23ccf..76296a6a33b 100644 --- a/netbox/extras/forms/bulk_import.py +++ b/netbox/extras/forms/bulk_import.py @@ -167,7 +167,6 @@ class ConfigTemplateImportForm(CSVModelForm): to_field_name='name', help_text=_('Data source which provides the data file') ) - data_file = CSVModelChoiceField( label=_('DataFile'), queryset=DataFile.objects.all(), @@ -175,13 +174,11 @@ class ConfigTemplateImportForm(CSVModelForm): to_field_name='path', help_text=_('DataFile containing the template code') ) - template_code = forms.CharField( label=_('Template code'), required=False, widget=forms.Textarea(attrs={'class': 'font-monospace'}) ) - auto_sync_enabled = forms.BooleanField( required=False, label=_('auto sync enabled'), From 0b233b47d6c9d88c2fda0cd343695e1d1072fe52 Mon Sep 17 00:00:00 2001 From: Idris Foughali Date: Thu, 13 Nov 2025 06:55:35 +0000 Subject: [PATCH 10/17] Feat: renamed data_file label to human-friendly --- netbox/extras/forms/bulk_import.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/netbox/extras/forms/bulk_import.py b/netbox/extras/forms/bulk_import.py index 76296a6a33b..dea462f7b87 100644 --- a/netbox/extras/forms/bulk_import.py +++ b/netbox/extras/forms/bulk_import.py @@ -168,7 +168,7 @@ class ConfigTemplateImportForm(CSVModelForm): help_text=_('Data source which provides the data file') ) data_file = CSVModelChoiceField( - label=_('DataFile'), + label=_('Data file'), queryset=DataFile.objects.all(), required=False, to_field_name='path', From 1de7ecd346a805d612d2593d25cd979694c46080 Mon Sep 17 00:00:00 2001 From: Idris Foughali Date: Thu, 13 Nov 2025 06:56:02 +0000 Subject: [PATCH 11/17] Feat: enhanced helper text of data_file attribute --- netbox/extras/forms/bulk_import.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/netbox/extras/forms/bulk_import.py b/netbox/extras/forms/bulk_import.py index dea462f7b87..0b06e718a86 100644 --- a/netbox/extras/forms/bulk_import.py +++ b/netbox/extras/forms/bulk_import.py @@ -172,7 +172,7 @@ class ConfigTemplateImportForm(CSVModelForm): queryset=DataFile.objects.all(), required=False, to_field_name='path', - help_text=_('DataFile containing the template code') + help_text=_('Data file containing the template code') ) template_code = forms.CharField( label=_('Template code'), From aa4a7aaa9a55d2fba4e03e8558fd1123c2d8563d Mon Sep 17 00:00:00 2001 From: Idris Foughali Date: Thu, 13 Nov 2025 06:57:26 +0000 Subject: [PATCH 12/17] Feat: removed already supported template_code attribute from ConfigTemplateImportForm --- netbox/extras/forms/bulk_import.py | 5 ----- 1 file changed, 5 deletions(-) diff --git a/netbox/extras/forms/bulk_import.py b/netbox/extras/forms/bulk_import.py index 0b06e718a86..db9bce08f0d 100644 --- a/netbox/extras/forms/bulk_import.py +++ b/netbox/extras/forms/bulk_import.py @@ -174,11 +174,6 @@ class ConfigTemplateImportForm(CSVModelForm): to_field_name='path', help_text=_('Data file containing the template code') ) - template_code = forms.CharField( - label=_('Template code'), - required=False, - widget=forms.Textarea(attrs={'class': 'font-monospace'}) - ) auto_sync_enabled = forms.BooleanField( required=False, label=_('auto sync enabled'), From dd3ce38a205386f8b760f9fb8fe238e9ea8845e3 Mon Sep 17 00:00:00 2001 From: Idris Foughali Date: Thu, 13 Nov 2025 06:58:14 +0000 Subject: [PATCH 13/17] Style: capitalized label for auto_sync_enabled --- netbox/extras/forms/bulk_import.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/netbox/extras/forms/bulk_import.py b/netbox/extras/forms/bulk_import.py index db9bce08f0d..9e5c6239ca3 100644 --- a/netbox/extras/forms/bulk_import.py +++ b/netbox/extras/forms/bulk_import.py @@ -176,7 +176,7 @@ class ConfigTemplateImportForm(CSVModelForm): ) auto_sync_enabled = forms.BooleanField( required=False, - label=_('auto sync enabled'), + label=_('Auto sync enabled'), help_text=_("Enable automatic synchronization of data when the data file is updated") ) From 1b1d7fba96f82a3a54ff5734804191d8217d1f8a Mon Sep 17 00:00:00 2001 From: Idris Foughali Date: Thu, 13 Nov 2025 06:59:30 +0000 Subject: [PATCH 14/17] Style: enhanced helper text for auto_sync_enabled attribute --- netbox/extras/forms/bulk_import.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/netbox/extras/forms/bulk_import.py b/netbox/extras/forms/bulk_import.py index 9e5c6239ca3..44f387eeb06 100644 --- a/netbox/extras/forms/bulk_import.py +++ b/netbox/extras/forms/bulk_import.py @@ -177,7 +177,7 @@ class ConfigTemplateImportForm(CSVModelForm): auto_sync_enabled = forms.BooleanField( required=False, label=_('Auto sync enabled'), - help_text=_("Enable automatic synchronization of data when the data file is updated") + help_text=_("Enable automatic synchronization of template content when the data file is updated") ) class Meta: From e20ab146f2a39072728b9efba4746539ec317285 Mon Sep 17 00:00:00 2001 From: Idris Foughali Date: Thu, 13 Nov 2025 07:05:10 +0000 Subject: [PATCH 15/17] Style: 120 chars line collapse --- netbox/extras/forms/bulk_import.py | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/netbox/extras/forms/bulk_import.py b/netbox/extras/forms/bulk_import.py index 44f387eeb06..38c645ee81d 100644 --- a/netbox/extras/forms/bulk_import.py +++ b/netbox/extras/forms/bulk_import.py @@ -182,10 +182,9 @@ class ConfigTemplateImportForm(CSVModelForm): class Meta: model = ConfigTemplate - fields = ( - 'name', 'description', 'template_code', 'data_source', 'data_file', - 'auto_sync_enabled', 'environment_params', 'mime_type', 'file_name', - 'file_extension', 'as_attachment', 'tags', + fields = ( + 'name', 'description', 'template_code', 'data_source', 'data_file', 'auto_sync_enabled', + 'environment_params', 'mime_type', 'file_name', 'file_extension', 'as_attachment', 'tags', ) def clean_template_code(self): From 41d5e139e630b0d0f743d38e746d3e9e3d66ea4b Mon Sep 17 00:00:00 2001 From: Idris Foughali Date: Thu, 13 Nov 2025 07:12:53 +0000 Subject: [PATCH 16/17] Feat: moved clean_template_code logic to clean method --- netbox/extras/forms/bulk_import.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/netbox/extras/forms/bulk_import.py b/netbox/extras/forms/bulk_import.py index 38c645ee81d..4efe3a2bb32 100644 --- a/netbox/extras/forms/bulk_import.py +++ b/netbox/extras/forms/bulk_import.py @@ -187,11 +187,12 @@ class Meta: 'environment_params', 'mime_type', 'file_name', 'file_extension', 'as_attachment', 'tags', ) - def clean_template_code(self): + def clean(self): + super().clean() + # Make sure template_code is None when it's not included in the uploaded data if not self.data.get('template_code') and not self.data.get('data_file'): raise forms.ValidationError(_("Must specify either local content or a data file")) - return self.cleaned_data['template_code'] def clean_auto_sync_enabled(self): From 2871944faf349ea254f4690fb7a5c5a2354bbe1b Mon Sep 17 00:00:00 2001 From: Idris Foughali Date: Thu, 13 Nov 2025 07:13:54 +0000 Subject: [PATCH 17/17] Feat: removed uncessary clean on boolean attribute --- netbox/extras/forms/bulk_import.py | 6 ------ 1 file changed, 6 deletions(-) diff --git a/netbox/extras/forms/bulk_import.py b/netbox/extras/forms/bulk_import.py index 4efe3a2bb32..2bc14949127 100644 --- a/netbox/extras/forms/bulk_import.py +++ b/netbox/extras/forms/bulk_import.py @@ -195,12 +195,6 @@ def clean(self): raise forms.ValidationError(_("Must specify either local content or a data file")) return self.cleaned_data['template_code'] - def clean_auto_sync_enabled(self): - # Make sure is_primary is None when it's not included in the uploaded data - if not self.data.get('auto_sync_enabled'): - self.cleaned_data['auto_sync_enabled'] = False - return self.cleaned_data['auto_sync_enabled'] - class SavedFilterImportForm(CSVModelForm): object_types = CSVMultipleContentTypeField(