Enable changelog messages for single object operations

This commit is contained in:
Jeremy Stretch 2025-07-17 16:37:42 -04:00
parent 5e5c46f77c
commit 8d5436876e
6 changed files with 40 additions and 6 deletions

View File

@ -11,7 +11,7 @@ from extras.models import CustomField, Tag
from utilities.forms import BulkEditForm, CSVModelForm
from utilities.forms.fields import CSVModelMultipleChoiceField, DynamicModelMultipleChoiceField
from utilities.forms.mixins import CheckLastUpdatedMixin
from .mixins import CustomFieldsMixin, SavedFiltersMixin, TagsMixin
from .mixins import ChangeLoggingMixin, CustomFieldsMixin, SavedFiltersMixin, TagsMixin
__all__ = (
'NetBoxModelForm',
@ -21,7 +21,7 @@ __all__ = (
)
class NetBoxModelForm(CheckLastUpdatedMixin, CustomFieldsMixin, TagsMixin, forms.ModelForm):
class NetBoxModelForm(ChangeLoggingMixin, CheckLastUpdatedMixin, CustomFieldsMixin, TagsMixin, forms.ModelForm):
"""
Base form for creating & editing NetBox models. Extends Django's ModelForm to add support for custom fields.

View File

@ -7,12 +7,27 @@ from extras.models import *
from utilities.forms.fields import DynamicModelMultipleChoiceField
__all__ = (
'ChangeLoggingMixin',
'CustomFieldsMixin',
'SavedFiltersMixin',
'TagsMixin',
)
class ChangeLoggingMixin(forms.Form):
changelog_message = forms.CharField(
required=False,
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:
"""
Extend a Form to include custom field support.

View File

@ -63,6 +63,8 @@ class ChangeLoggingMixin(DeleteMixin, models.Model):
null=True
)
_changelog_message = None
class Meta:
abstract = True
@ -103,7 +105,8 @@ class ChangeLoggingMixin(DeleteMixin, models.Model):
objectchange = ObjectChange(
changed_object=self,
object_repr=str(self)[:200],
action=action
action=action,
message=self._changelog_message or '',
)
if hasattr(self, '_prechange_snapshot'):
objectchange.prechange_data = self._prechange_snapshot

View File

@ -19,7 +19,7 @@ from netbox.object_actions import (
)
from utilities.error_handlers import handle_protectederror
from utilities.exceptions import AbortRequest, PermissionsViolation
from utilities.forms import ConfirmationForm, restrict_form_fields
from utilities.forms import DeleteForm, restrict_form_fields
from utilities.htmx import htmx_partial
from utilities.permissions import get_permission_for_model
from utilities.querydict import normalize_querydict, prepare_cloned_fields
@ -422,7 +422,7 @@ class ObjectDeleteView(GetReturnURLMixin, BaseObjectView):
request: The current request
"""
obj = self.get_object(**kwargs)
form = ConfirmationForm(initial=request.GET)
form = DeleteForm(initial=request.GET)
try:
dependent_objects = self._get_dependent_objects(obj)
@ -461,7 +461,7 @@ class ObjectDeleteView(GetReturnURLMixin, BaseObjectView):
"""
logger = logging.getLogger('netbox.views.ObjectDeleteView')
obj = self.get_object(**kwargs)
form = ConfirmationForm(request.POST)
form = DeleteForm(request.POST)
# Take a snapshot of change-logged models
if hasattr(obj, 'snapshot'):
@ -469,6 +469,7 @@ class ObjectDeleteView(GetReturnURLMixin, BaseObjectView):
if form.is_valid():
logger.debug("Form validation was successful")
obj._changelog_message = form.cleaned_data.pop('changelog_message', '')
try:
obj.delete()

View File

@ -28,6 +28,10 @@
</div>
{% endif %}
{% if form.changelog_message %}
{% render_field form.changelog_message %}
{% endif %}
{% else %}
{# Render all fields in a single group #}

View File

@ -10,6 +10,7 @@ __all__ = (
'BulkRenameForm',
'ConfirmationForm',
'CSVModelForm',
'DeleteForm',
'FilterForm',
'TableConfigForm',
)
@ -30,6 +31,16 @@ class ConfirmationForm(forms.Form):
)
class DeleteForm(ConfirmationForm):
"""
Confirm the deletion of an object, optionally providing a changelog message.
"""
changelog_message = forms.CharField(
required=False,
max_length=200
)
class BulkEditForm(BackgroundJobMixin, forms.Form):
"""
Provides bulk edit support for objects.