mirror of
https://github.com/netbox-community/netbox.git
synced 2025-07-23 17:08:41 -06:00
Add changelog message support for bulk edit & bulk delete
This commit is contained in:
parent
1b11895c90
commit
0703fe7852
@ -100,7 +100,7 @@ class NetBoxModelImportForm(CSVModelForm, NetBoxModelForm):
|
||||
return customfield.to_form_field(for_csv_import=True)
|
||||
|
||||
|
||||
class NetBoxModelBulkEditForm(CustomFieldsMixin, BulkEditForm):
|
||||
class NetBoxModelBulkEditForm(ChangeLoggingMixin, CustomFieldsMixin, BulkEditForm):
|
||||
"""
|
||||
Base form for modifying multiple NetBox objects (of the same type) in bulk via the UI. Adds support for custom
|
||||
fields and adding/removing tags.
|
||||
|
@ -20,13 +20,6 @@ class ChangeLoggingMixin(forms.Form):
|
||||
max_length=200
|
||||
)
|
||||
|
||||
def clean(self):
|
||||
|
||||
# Attach the changelog message (if any) to the instance
|
||||
self.instance._changelog_message = self.cleaned_data.pop('changelog_message', None)
|
||||
|
||||
return self.cleaned_data
|
||||
|
||||
|
||||
class CustomFieldsMixin:
|
||||
"""
|
||||
|
@ -21,6 +21,7 @@ from core.models import ObjectType
|
||||
from core.signals import clear_events
|
||||
from extras.choices import CustomFieldUIEditableChoices
|
||||
from extras.models import CustomField, ExportTemplate
|
||||
from netbox.forms.mixins import ChangeLoggingMixin
|
||||
from netbox.object_actions import AddObject, BulkDelete, BulkEdit, BulkExport, BulkImport, BulkRename
|
||||
from utilities.error_handlers import handle_protectederror
|
||||
from utilities.exceptions import AbortRequest, AbortTransaction, PermissionsViolation
|
||||
@ -622,6 +623,9 @@ class BulkEditView(GetReturnURLMixin, BaseMultiObjectView):
|
||||
if hasattr(obj, 'snapshot'):
|
||||
obj.snapshot()
|
||||
|
||||
# Attach the changelog message (if any) to the object
|
||||
obj._changelog_message = form.cleaned_data.get('changelog_message')
|
||||
|
||||
# Update standard fields. If a field is listed in _nullify, delete its value.
|
||||
for name, model_field in model_fields.items():
|
||||
# Handle nullification
|
||||
@ -892,7 +896,7 @@ class BulkDeleteView(GetReturnURLMixin, BaseMultiObjectView):
|
||||
"""
|
||||
Provide a standard bulk delete form if none has been specified for the view
|
||||
"""
|
||||
class BulkDeleteForm(BackgroundJobMixin, ConfirmationForm):
|
||||
class BulkDeleteForm(BackgroundJobMixin, ChangeLoggingMixin, ConfirmationForm):
|
||||
pk = ModelMultipleChoiceField(queryset=self.queryset, widget=MultipleHiddenInput)
|
||||
|
||||
return BulkDeleteForm
|
||||
@ -939,9 +943,15 @@ class BulkDeleteView(GetReturnURLMixin, BaseMultiObjectView):
|
||||
try:
|
||||
with transaction.atomic(using=router.db_for_write(model)):
|
||||
for obj in queryset:
|
||||
|
||||
# Take a snapshot of change-logged models
|
||||
if hasattr(obj, 'snapshot'):
|
||||
obj.snapshot()
|
||||
|
||||
# Attach the changelog message (if any) to the object
|
||||
obj._changelog_message = form.cleaned_data.get('changelog_message')
|
||||
|
||||
# Delete the object
|
||||
obj.delete()
|
||||
|
||||
except (ProtectedError, RestrictedError) as e:
|
||||
|
@ -288,6 +288,9 @@ class ObjectEditView(GetReturnURLMixin, BaseObjectView):
|
||||
if form.is_valid():
|
||||
logger.debug("Form validation was successful")
|
||||
|
||||
# Record changelog message (if any)
|
||||
obj._changelog_message = form.cleaned_data.pop('changelog_message', '')
|
||||
|
||||
try:
|
||||
with transaction.atomic(using=router.db_for_write(model)):
|
||||
object_created = form.instance.pk is None
|
||||
@ -463,22 +466,23 @@ class ObjectDeleteView(GetReturnURLMixin, BaseObjectView):
|
||||
obj = self.get_object(**kwargs)
|
||||
form = DeleteForm(request.POST)
|
||||
|
||||
# Take a snapshot of change-logged models
|
||||
if hasattr(obj, 'snapshot'):
|
||||
obj.snapshot()
|
||||
|
||||
if form.is_valid():
|
||||
logger.debug("Form validation was successful")
|
||||
|
||||
# Take a snapshot of change-logged models
|
||||
if hasattr(obj, 'snapshot'):
|
||||
obj.snapshot()
|
||||
|
||||
# Record changelog message (if any)
|
||||
obj._changelog_message = form.cleaned_data.pop('changelog_message', '')
|
||||
|
||||
# Delete the object
|
||||
try:
|
||||
obj.delete()
|
||||
|
||||
except (ProtectedError, RestrictedError) as e:
|
||||
logger.info(f"Caught {type(e)} while attempting to delete objects")
|
||||
handle_protectederror([obj], request, e)
|
||||
return redirect(obj.get_absolute_url())
|
||||
|
||||
except AbortRequest as e:
|
||||
logger.debug(e.message)
|
||||
messages.error(request, mark_safe(e.message))
|
||||
|
@ -67,6 +67,7 @@ Context:
|
||||
|
||||
{# Meta fields #}
|
||||
<div class="bg-primary-subtle border border-primary rounded-1 pt-3 mb-3">
|
||||
{% render_field form.changelog_message %}
|
||||
{% render_field form.background_job %}
|
||||
</div>
|
||||
|
||||
|
@ -104,6 +104,7 @@ Context:
|
||||
|
||||
{# Meta fields #}
|
||||
<div class="bg-primary-subtle border border-primary rounded-1 pt-3 mb-3">
|
||||
{% render_field form.changelog_message %}
|
||||
{% render_field form.background_job %}
|
||||
</div>
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user