Show the peer device/port in component connection columns

Add ConceptComponent.peer, returning the component on the other end
of its cable (whichever termination isn't itself). Use it in the
component tables' "Connection" column (Device > Port, both linked,
mirroring NetBox's own link_peer style) instead of just linking to the
cable object, and on the component detail page's "Connected to" row
in place of the manual termination_a/b branch.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
2026-09-16 10:58:47 +02:00
co-authored by Claude Sonnet 5
parent 8818065840
commit d500a7b184
3 changed files with 24 additions and 12 deletions
+8
View File
@@ -542,6 +542,14 @@ class ConceptComponent(NetBoxModel):
def is_connected(self): def is_connected(self):
return self.cable is not None return self.cable is not None
@property
def peer(self):
"""The component on the other end of this component's cable, if any."""
cable = self.cable
if cable is None:
return None
return cable.termination_b if cable.termination_a_id == self.pk else cable.termination_a
def get_paired_components(self): def get_paired_components(self):
""" """
For a front or rear port, the port(s) on the other side it passes through to - For a front or rear port, the port(s) on the other side it passes through to -
+15 -5
View File
@@ -115,8 +115,21 @@ class ConceptComponentTable(NetBoxTable):
concept = tables.Column(accessor='device__concept', linkify=True, verbose_name=_('Concept')) concept = tables.Column(accessor='device__concept', linkify=True, verbose_name=_('Concept'))
component_type = columns.ChoiceFieldColumn() component_type = columns.ChoiceFieldColumn()
color = columns.ColorColumn() color = columns.ColorColumn()
connection = tables.Column( connection = tables.TemplateColumn(
accessor='cable', linkify=True, orderable=False, verbose_name=_('Connection'), empty_values=() template_code="""
{% with peer=record.peer %}
{% if peer %}
<a href="{{ peer.device.get_absolute_url }}">{{ peer.device }}</a>
<i class="mdi mdi-chevron-right"></i>
<a href="{{ peer.get_absolute_url }}">{{ peer }}</a>
{% else %}
{{ ''|placeholder }}
{% endif %}
{% endwith %}
""",
verbose_name=_('Connection'),
orderable=False,
empty_values=()
) )
connect = tables.TemplateColumn( connect = tables.TemplateColumn(
template_code=""" template_code="""
@@ -139,9 +152,6 @@ class ConceptComponentTable(NetBoxTable):
) )
default_columns = ('name', 'device', 'component_type', 'port_type', 'connection', 'connect') default_columns = ('name', 'device', 'component_type', 'port_type', 'connection', 'connect')
def render_connection(self, value, record):
return value if value else _('Not connected')
class ConceptCableTable(NetBoxTable): class ConceptCableTable(NetBoxTable):
id = tables.Column(linkify=True, verbose_name=_('ID')) id = tables.Column(linkify=True, verbose_name=_('ID'))
@@ -91,13 +91,7 @@
</tr> </tr>
<tr> <tr>
<th scope="row">{% trans "Connected to" %}</th> <th scope="row">{% trans "Connected to" %}</th>
<td> <td>{{ object.peer.device|linkify }} &middot; {{ object.peer|linkify }}</td>
{% if cable.termination_a_id == object.pk %}
{{ cable.termination_b.device|linkify }} &middot; {{ cable.termination_b|linkify }}
{% else %}
{{ cable.termination_a.device|linkify }} &middot; {{ cable.termination_a|linkify }}
{% endif %}
</td>
</tr> </tr>
</table> </table>
{% else %} {% else %}