diff --git a/netbox/dcim/tables/cables.py b/netbox/dcim/tables/cables.py
index f3643dd1b..ff2a672ca 100644
--- a/netbox/dcim/tables/cables.py
+++ b/netbox/dcim/tables/cables.py
@@ -1,5 +1,6 @@
import django_tables2 as tables
from django_tables2.utils import Accessor
+from django.utils.safestring import mark_safe
from dcim.models import Cable
from netbox.tables import NetBoxTable, columns
@@ -11,20 +12,34 @@ __all__ = (
)
-class CableTerminationsColumn(tables.TemplateColumn):
+class CableTerminationsColumn(tables.Column):
+ """
+ Args:
+ cable_end: Which side of the cable to report on (A or B)
+ attr: The CableTermination attribute to return for each instance (returns the termination object by default)
+ """
+ def __init__(self, cable_end, attr='termination', *args, **kwargs):
+ self.cable_end = cable_end
+ self.attr = attr
+ super().__init__(accessor=Accessor('terminations'), *args, **kwargs)
- def __init__(self, cable_end, *args, **kwargs):
- template_code = """
- {% for term in value.all %}
- {% if term.cable_end == '""" + cable_end + """' %}
- {{ term.termination }}
- {% endif %}
- {% endfor %}
- """
- super().__init__(template_code=template_code, *args, **kwargs)
+ def _get_terminations(self, manager):
+ terminations = set()
+ for cabletermination in manager.all():
+ if cabletermination.cable_end == self.cable_end:
+ if termination := getattr(cabletermination, self.attr, None):
+ terminations.add(termination)
+
+ return terminations
+
+ def render(self, value):
+ links = [
+ f'{term}' for term in self._get_terminations(value)
+ ]
+ return mark_safe('
'.join(links) or '—')
def value(self, value):
- return ', '.join([str(t.termination) for t in value.all()])
+ return ','.join([str(t) for t in self._get_terminations(value)])
#
@@ -32,41 +47,63 @@ class CableTerminationsColumn(tables.TemplateColumn):
#
class CableTable(NetBoxTable):
- # termination_a_parent = tables.TemplateColumn(
- # template_code=CABLE_TERMINATION_PARENT,
- # accessor=Accessor('termination_a'),
- # orderable=False,
- # verbose_name='Side A'
- # )
- # rack_a = tables.Column(
- # accessor=Accessor('termination_a__device__rack'),
- # orderable=False,
- # linkify=True,
- # verbose_name='Rack A'
- # )
- # termination_b_parent = tables.TemplateColumn(
- # template_code=CABLE_TERMINATION_PARENT,
- # accessor=Accessor('termination_b'),
- # orderable=False,
- # verbose_name='Side B'
- # )
- # rack_b = tables.Column(
- # accessor=Accessor('termination_b__device__rack'),
- # orderable=False,
- # linkify=True,
- # verbose_name='Rack B'
- # )
a_terminations = CableTerminationsColumn(
cable_end='A',
- accessor=Accessor('terminations'),
orderable=False,
- verbose_name='A Side'
+ verbose_name='Termination A'
)
b_terminations = CableTerminationsColumn(
cable_end='B',
- accessor=Accessor('terminations'),
orderable=False,
- verbose_name='B Side'
+ verbose_name='Termination B'
+ )
+ device_a = CableTerminationsColumn(
+ cable_end='A',
+ attr='_device',
+ orderable=False,
+ verbose_name='Device A'
+ )
+ device_b = CableTerminationsColumn(
+ cable_end='B',
+ attr='_device',
+ orderable=False,
+ verbose_name='Device B'
+ )
+ location_a = CableTerminationsColumn(
+ cable_end='A',
+ attr='_location',
+ orderable=False,
+ verbose_name='Location A'
+ )
+ location_b = CableTerminationsColumn(
+ cable_end='B',
+ attr='_location',
+ orderable=False,
+ verbose_name='Location B'
+ )
+ rack_a = CableTerminationsColumn(
+ cable_end='A',
+ attr='_rack',
+ orderable=False,
+ verbose_name='Rack A'
+ )
+ rack_b = CableTerminationsColumn(
+ cable_end='B',
+ attr='_rack',
+ orderable=False,
+ verbose_name='Rack B'
+ )
+ site_a = CableTerminationsColumn(
+ cable_end='A',
+ attr='_site',
+ orderable=False,
+ verbose_name='Site A'
+ )
+ site_b = CableTerminationsColumn(
+ cable_end='B',
+ attr='_site',
+ orderable=False,
+ verbose_name='Site B'
)
status = columns.ChoiceFieldColumn()
tenant = TenantColumn()
@@ -82,8 +119,9 @@ class CableTable(NetBoxTable):
class Meta(NetBoxTable.Meta):
model = Cable
fields = (
- 'pk', 'id', 'label', 'a_terminations', 'b_terminations', 'status', 'type', 'tenant', 'color', 'length',
- 'tags', 'created', 'last_updated',
+ 'pk', 'id', 'label', 'a_terminations', 'b_terminations', 'device_a', 'device_b', 'rack_a', 'rack_b',
+ 'location_a', 'location_b', 'site_a', 'site_b', 'status', 'type', 'tenant', 'color', 'length', 'tags',
+ 'created', 'last_updated',
)
default_columns = (
'pk', 'id', 'label', 'a_terminations', 'b_terminations', 'status', 'type',
diff --git a/netbox/dcim/views.py b/netbox/dcim/views.py
index 5619329ac..1f2f04d7a 100644
--- a/netbox/dcim/views.py
+++ b/netbox/dcim/views.py
@@ -2756,7 +2756,10 @@ class DeviceBulkAddInventoryItemView(generic.BulkComponentCreateView):
#
class CableListView(generic.ObjectListView):
- queryset = Cable.objects.prefetch_related('terminations__termination')
+ queryset = Cable.objects.prefetch_related(
+ 'terminations__termination', 'terminations___device', 'terminations___rack', 'terminations___location',
+ 'terminations___site',
+ )
filterset = filtersets.CableFilterSet
filterset_form = forms.CableFilterForm
table = tables.CableTable