From f49d7be00f9daf602d1bf7c9a7235f153c97759d Mon Sep 17 00:00:00 2001 From: Arthur Date: Wed, 16 Sep 2026 09:48:45 -0700 Subject: [PATCH] simplify --- netbox/circuits/models/circuits.py | 31 ++++++++++++++---------------- 1 file changed, 14 insertions(+), 17 deletions(-) diff --git a/netbox/circuits/models/circuits.py b/netbox/circuits/models/circuits.py index 67d88ff48..6c095de9b 100644 --- a/netbox/circuits/models/circuits.py +++ b/netbox/circuits/models/circuits.py @@ -241,6 +241,15 @@ class CircuitGroupAssignment(CustomFieldsMixin, ExportTemplatesMixin, TagsMixin, return reverse('circuits:circuitgroupassignment', args=[self.pk]) +def _set_circuit_termination(circuit, field_name, value): + """ + Set or clear a Circuit's cached `termination_a`/`termination_z` field, recording the change. + """ + circuit.snapshot() + setattr(circuit, field_name, value) + circuit.save(update_fields=[field_name, 'last_updated']) + + class CircuitTermination( CustomFieldsMixin, CustomLinksMixin, @@ -400,43 +409,31 @@ class CircuitTermination( super().save(*args, **kwargs) - # Clear the old termination reference if circuit or term_side changed. Written via - # snapshot() + save() rather than a queryset update(), which emits no post_save and so - # records nothing in the changelog (#23134). Matching on the pointer's current value - # skips the write unless it actually references this termination. + # Clear the old termination reference if circuit or term_side changed if circuit_changed or term_side_changed: old_termination_name = f'termination_{self._orig_term_side.lower()}' circuit = Circuit.objects.filter( pk=self._orig_circuit_id, **{old_termination_name: self.pk} ).first() if circuit is not None: - circuit.snapshot() - setattr(circuit, old_termination_name, None) - circuit.save(update_fields=[old_termination_name, 'last_updated']) + _set_circuit_termination(circuit, old_termination_name, None) # Update the cache if this is a new termination or circuit/term_side changed if is_new or circuit_changed or term_side_changed: # Update the new circuit's termination reference termination_name = f'termination_{self.term_side.lower()}' - # Re-fetched rather than reusing self.circuit, whose pointers may predate a sibling write - circuit = Circuit.objects.get(pk=self.circuit_id) - circuit.snapshot() - setattr(circuit, termination_name, self) - circuit.save(update_fields=[termination_name, 'last_updated']) + _set_circuit_termination(Circuit.objects.get(pk=self.circuit_id), termination_name, self) # Update cached values for subsequent saves self._orig_circuit_id = self.circuit_id self._orig_term_side = self.term_side def delete(self, *args, **kwargs): - # on_delete=SET_NULL would clear the circuit's reference with an unlogged bulk update. - # Clearing it here instead also puts the record ahead of the DELETE. + # Clear the circuit's reference here; on_delete=SET_NULL is not change-logged termination_name = f'termination_{self.term_side.lower()}' circuit = Circuit.objects.filter(pk=self.circuit_id, **{termination_name: self.pk}).first() if circuit is not None: - circuit.snapshot() - setattr(circuit, termination_name, None) - circuit.save(update_fields=[termination_name, 'last_updated']) + _set_circuit_termination(circuit, termination_name, None) return super().delete(*args, **kwargs)