14147 Prevent logging to Change Log when no changes are made (#14477)

* 14147 Prevent logging to Change Log when no changes are made

* 14147 add test

* 14147 add exclude_fields to serialize_object

* 14147 make skip empty default to True

* 14147 remove override of to_objectchange

* Misc cleanup

---------

Co-authored-by: Jeremy Stretch <jstretch@netboxlabs.com>
This commit is contained in:
Arthur Hanson
2023-12-15 12:17:45 -08:00
committed by GitHub
parent 965f2de34b
commit 224d64007a
7 changed files with 112 additions and 14 deletions
+4
View File
@@ -135,3 +135,7 @@ class ObjectChange(models.Model):
def get_action_color(self):
return ObjectChangeActionChoices.colors.get(self.action)
@property
def has_changes(self):
return self.prechange_data != self.postchange_data
+4 -3
View File
@@ -80,9 +80,10 @@ def handle_changed_object(sender, instance, **kwargs):
)
else:
objectchange = instance.to_objectchange(action)
objectchange.user = request.user
objectchange.request_id = request.id
objectchange.save()
if objectchange and objectchange.has_changes:
objectchange.user = request.user
objectchange.request_id = request.id
objectchange.save()
# If this is an M2M change, update the previously queued webhook (from post_save)
queue = events_queue.get()
+61
View File
@@ -1,4 +1,5 @@
from django.contrib.contenttypes.models import ContentType
from django.test import override_settings
from django.urls import reverse
from rest_framework import status
@@ -207,6 +208,66 @@ class ChangeLogViewTest(ModelViewTestCase):
self.assertEqual(objectchange.prechange_data['slug'], sites[0].slug)
self.assertEqual(objectchange.postchange_data, None)
@override_settings(CHANGELOG_SKIP_EMPTY_CHANGES=False)
def test_update_object_change(self):
# Create a Site
site = Site.objects.create(
name='Site 1',
slug='site-1',
status=SiteStatusChoices.STATUS_PLANNED,
custom_field_data={
'cf1': None,
'cf2': None
}
)
# Update it with the same field values
form_data = {
'name': site.name,
'slug': site.slug,
'status': SiteStatusChoices.STATUS_PLANNED,
}
request = {
'path': self._get_url('edit', instance=site),
'data': post_data(form_data),
}
self.add_permissions('dcim.change_site', 'extras.view_tag')
response = self.client.post(**request)
self.assertHttpStatus(response, 302)
# Check that an ObjectChange record has been created
self.assertEqual(ObjectChange.objects.count(), 1)
@override_settings(CHANGELOG_SKIP_EMPTY_CHANGES=True)
def test_update_object_nochange(self):
# Create a Site
site = Site.objects.create(
name='Site 1',
slug='site-1',
status=SiteStatusChoices.STATUS_PLANNED,
custom_field_data={
'cf1': None,
'cf2': None
}
)
# Update it with the same field values
form_data = {
'name': site.name,
'slug': site.slug,
'status': SiteStatusChoices.STATUS_PLANNED,
}
request = {
'path': self._get_url('edit', instance=site),
'data': post_data(form_data),
}
self.add_permissions('dcim.change_site', 'extras.view_tag')
response = self.client.post(**request)
self.assertHttpStatus(response, 302)
# Check that no ObjectChange records have been created
self.assertEqual(ObjectChange.objects.count(), 0)
class ChangeLogAPITest(APITestCase):