diff --git a/netbox/netbox/forms/mixins.py b/netbox/netbox/forms/mixins.py index 4c9e46c0e..8ecca73e1 100644 --- a/netbox/netbox/forms/mixins.py +++ b/netbox/netbox/forms/mixins.py @@ -15,6 +15,9 @@ __all__ = ( class ChangeLoggingMixin(forms.Form): + """ + Adds an optional field for recording a message on the resulting changelog record(s). + """ changelog_message = forms.CharField( required=False, max_length=200 diff --git a/netbox/netbox/views/generic/bulk_views.py b/netbox/netbox/views/generic/bulk_views.py index 246f41f3b..36223fd20 100644 --- a/netbox/netbox/views/generic/bulk_views.py +++ b/netbox/netbox/views/generic/bulk_views.py @@ -424,7 +424,6 @@ class BulkImportView(GetReturnURLMixin, BaseMultiObjectView): } if prefetch_ids else {} for i, record in enumerate(records, start=1): - instance = None object_id = int(record.pop('id')) if record.get('id') else None # Determine whether this object is being created or updated @@ -440,6 +439,8 @@ class BulkImportView(GetReturnURLMixin, BaseMultiObjectView): instance.snapshot() else: + instance = self.queryset.model() + # For newly created objects, apply any default custom field values custom_fields = CustomField.objects.filter( object_types=ContentType.objects.get_for_model(self.queryset.model), @@ -450,6 +451,9 @@ class BulkImportView(GetReturnURLMixin, BaseMultiObjectView): if field_name not in record: record[field_name] = cf.default + # Record changelog message (if any) + instance._changelog_message = form.cleaned_data.pop('changelog_message', '') + # Instantiate the model form for the object model_form_kwargs = { 'data': record, diff --git a/netbox/templates/generic/bulk_import.html b/netbox/templates/generic/bulk_import.html index f4a67cc1f..0e83afcb3 100644 --- a/netbox/templates/generic/bulk_import.html +++ b/netbox/templates/generic/bulk_import.html @@ -42,32 +42,31 @@ Context: {# Data Import Form #}
-
-
-
- {% csrf_token %} - +
+ + {% csrf_token %} + - {# Form fields #} - {% render_field form.data %} - {% render_field form.format %} - {% render_field form.csv_delimiter %} + {# Form fields #} + {% render_field form.data %} + {% render_field form.format %} + {% render_field form.csv_delimiter %} - {# Meta fields #} -
- {% render_field form.background_job %} + {# Meta fields #} +
+ {% render_field form.changelog_message %} + {% render_field form.background_job %} +
+ +
+
+ {% if return_url %} + {% trans "Cancel" %} + {% endif %} +
- -
-
- {% if return_url %} - {% trans "Cancel" %} - {% endif %} - -
-
- -
+
+
@@ -83,6 +82,11 @@ Context: {% render_field form.format %} {% render_field form.csv_delimiter %} + {# Meta fields #} +
+ {% render_field form.changelog_message %} +
+
{% if return_url %} @@ -110,6 +114,7 @@ Context: {# Meta fields #}
+ {% render_field form.changelog_message %} {% render_field form.background_job %}
diff --git a/netbox/utilities/forms/bulk_import.py b/netbox/utilities/forms/bulk_import.py index b11f6688a..abebe255f 100644 --- a/netbox/utilities/forms/bulk_import.py +++ b/netbox/utilities/forms/bulk_import.py @@ -8,12 +8,13 @@ from django.utils.translation import gettext as _ from core.forms.mixins import SyncedDataMixin from netbox.choices import CSVDelimiterChoices, ImportFormatChoices, ImportMethodChoices +from netbox.forms.mixins import ChangeLoggingMixin from utilities.constants import CSV_DELIMITERS from utilities.forms.mixins import BackgroundJobMixin from utilities.forms.utils import parse_csv -class BulkImportForm(BackgroundJobMixin, SyncedDataMixin, forms.Form): +class BulkImportForm(ChangeLoggingMixin, BackgroundJobMixin, SyncedDataMixin, forms.Form): import_method = forms.ChoiceField( choices=ImportMethodChoices, required=False