Fixes #21127: Clear _path on interfaces when removed from cable

When editing a cable to remove an interface from the B side, the _path
field on the removed interface was not being cleared. This caused the
interface table to display stale connection info via _path.destinations.

Two changes:
- Signal handler now clears _path when termination removed from origins
- CablePath.delete() clears _path on origins (mirrors save() behavior)
This commit is contained in:
Jason Novinger
2026-02-13 09:01:11 -06:00
committed by Jeremy Stretch
parent de812a5a85
commit f113557e81
3 changed files with 16 additions and 1 deletions

View File

@@ -657,6 +657,16 @@ class CablePath(models.Model):
origin_ids = [decompile_path_node(node)[1] for node in self.path[0]]
origin_model.objects.filter(pk__in=origin_ids).update(_path=self.pk)
def delete(self, *args, **kwargs):
# Mirror save() - clear _path on origins to prevent stale references
# in table views that render _path.destinations
if self.path:
origin_model = self.origin_type.model_class()
origin_ids = [decompile_path_node(node)[1] for node in self.path[0]]
origin_model.objects.filter(pk__in=origin_ids, _path=self.pk).update(_path=None)
super().delete(*args, **kwargs)
@property
def origin_type(self):
if self.path:

View File

@@ -170,6 +170,8 @@ def nullify_connected_endpoints(instance, **kwargs):
# Remove the deleted CableTermination if it's one of the path's originating nodes
if instance.termination in cablepath.origins:
cablepath.origins.remove(instance.termination)
# Clear _path on the removed origin to prevent stale connection display
model.objects.filter(pk=instance.termination_id, _path=cablepath.pk).update(_path=None)
cablepath.retrace()

View File

@@ -2806,7 +2806,6 @@ class LegacyCablePathTests(CablePathTestCase):
interface2 = Interface.objects.create(device=self.device, name='Interface 2')
interface3 = Interface.objects.create(device=self.device, name='Interface 3')
# Create cables 1
cable1 = Cable(
a_terminations=[interface1],
b_terminations=[interface2, interface3]
@@ -2838,6 +2837,10 @@ class LegacyCablePathTests(CablePathTestCase):
is_active=True
)
# Verify _path is cleared on removed interface (#21127)
interface3.refresh_from_db()
self.assertPathIsNotSet(interface3)
def test_401_exclude_midspan_devices(self):
"""
[IF1] --C1-- [FP1][Test Device][RP1] --C2-- [RP2][Test Device][FP2] --C3-- [IF2]