From aa4a9da955e459e469e4c4cb6a3727ce1471ae0b Mon Sep 17 00:00:00 2001 From: Jeremy Stretch Date: Fri, 30 Jan 2026 14:49:12 -0500 Subject: [PATCH] Closes #21303: Cache serialized post-change data on object (#21325) * Closes #21303: Cache serialized post-change data on object * Set to_objectchange.alters_data * Restructure logic for determining post-change snapshot --- netbox/extras/events.py | 30 +++++++++++++++++++----------- netbox/netbox/models/features.py | 4 +++- 2 files changed, 22 insertions(+), 12 deletions(-) diff --git a/netbox/extras/events.py b/netbox/extras/events.py index 6ac78e19f..392071877 100644 --- a/netbox/extras/events.py +++ b/netbox/extras/events.py @@ -51,18 +51,26 @@ def serialize_for_event(instance): def get_snapshots(instance, event_type): - snapshots = { - 'prechange': getattr(instance, '_prechange_snapshot', None), - 'postchange': None, - } - if event_type != OBJECT_DELETED: - # Use model's serialize_object() method if defined; fall back to serialize_object() utility function - if hasattr(instance, 'serialize_object'): - snapshots['postchange'] = instance.serialize_object() - else: - snapshots['postchange'] = serialize_object(instance) + """ + Return a dictionary of pre- and post-change snapshots for the given instance. + """ + if event_type == OBJECT_DELETED: + # Post-change snapshot must be empty for deleted objects + postchange_snapshot = None + elif hasattr(instance, '_postchange_snapshot'): + # Use the cached post-change snapshot if one is available + postchange_snapshot = instance._postchange_snapshot + elif hasattr(instance, 'serialize_object'): + # Use model's serialize_object() method if defined + postchange_snapshot = instance.serialize_object() + else: + # Fall back to the serialize_object() utility function + postchange_snapshot = serialize_object(instance) - return snapshots + return { + 'prechange': getattr(instance, '_prechange_snapshot', None), + 'postchange': postchange_snapshot, + } def enqueue_event(queue, instance, request, event_type): diff --git a/netbox/netbox/models/features.py b/netbox/netbox/models/features.py index b6eb62884..7300340a8 100644 --- a/netbox/netbox/models/features.py +++ b/netbox/netbox/models/features.py @@ -121,9 +121,11 @@ class ChangeLoggingMixin(DeleteMixin, models.Model): if hasattr(self, '_prechange_snapshot'): objectchange.prechange_data = self._prechange_snapshot if action in (ObjectChangeActionChoices.ACTION_CREATE, ObjectChangeActionChoices.ACTION_UPDATE): - objectchange.postchange_data = self.serialize_object(exclude=exclude) + self._postchange_snapshot = self.serialize_object(exclude=exclude) + objectchange.postchange_data = self._postchange_snapshot return objectchange + to_objectchange.alters_data = True class CloningMixin(models.Model):