diff --git a/netbox/dcim/models/cables.py b/netbox/dcim/models/cables.py index 0a28d5acb9..b2b14a87fb 100644 --- a/netbox/dcim/models/cables.py +++ b/netbox/dcim/models/cables.py @@ -220,6 +220,7 @@ def save(self, *args, **kwargs): b_terminations = {ct.termination: ct for ct in self.terminations.filter(cable_end='B')} # Delete stale CableTerminations + if self._terminations_modified: for termination, ct in a_terminations.items(): if termination.pk and termination not in self.a_terminations: @@ -312,6 +313,12 @@ class Meta: def __str__(self): return f'Cable {self.cable} to {self.termination}' + def __init__(self, *args, **kwargs): + super().__init__(*args, **kwargs) + + self._orig_cable = self.__dict__.get('cable') + self._orig_cable_end = self.__dict__.get('cable_end') + def clean(self): super().clean() @@ -349,6 +356,7 @@ def save(self, *args, **kwargs): # Cache objects associated with the terminating object (for filtering) self.cache_related_objects() + created = self.pk is None super().save(*args, **kwargs) @@ -359,6 +367,28 @@ def save(self, *args, **kwargs): termination.cable_end = self.cable_end termination.save() + # figure out which cable terminations changed + if not created: + update_cable_termination = False + update_orig_cable_termination = False + + if self._orig_cable and self._orig_cable != self.cable: + update_cable_termination = True + update_orig_cable_termination = True + elif self._orig_cable_end and self._orig_cable_end != self.cable_end: + update_cable_termination = True + + if update_cable_termination: + self.cable._terminations_modified = True + trace_paths.send(Cable, instance=self.cable, created=False) + + if update_orig_cable_termination: + self._orig_cable._terminations_modified = True + trace_paths.send(Cable, instance=self._orig_cable, created=False) + + self._orig_cable_end = self.cable_end + self._orig_cable = self.cable + def delete(self, *args, **kwargs): # Delete the cable association on the terminating object @@ -369,6 +399,7 @@ def delete(self, *args, **kwargs): termination.save() super().delete(*args, **kwargs) + trace_paths.send(Cable, instance=self.cable, created=False) def cache_related_objects(self): """