Improve display of related objects in cables list

This commit is contained in:
jeremystretch 2022-07-08 13:33:43 -04:00
parent 42e5282283
commit ac4a87de13
2 changed files with 83 additions and 42 deletions

View File

@ -1,5 +1,6 @@
import django_tables2 as tables import django_tables2 as tables
from django_tables2.utils import Accessor from django_tables2.utils import Accessor
from django.utils.safestring import mark_safe
from dcim.models import Cable from dcim.models import Cable
from netbox.tables import NetBoxTable, columns 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): def _get_terminations(self, manager):
template_code = """ terminations = set()
{% for term in value.all %} for cabletermination in manager.all():
{% if term.cable_end == '""" + cable_end + """' %} if cabletermination.cable_end == self.cable_end:
<a href="{{ term.termination.get_absolute_url }}">{{ term.termination }}</a> if termination := getattr(cabletermination, self.attr, None):
{% endif %} terminations.add(termination)
{% endfor %}
""" return terminations
super().__init__(template_code=template_code, *args, **kwargs)
def render(self, value):
links = [
f'<a href="{term.get_absolute_url()}">{term}</a>' for term in self._get_terminations(value)
]
return mark_safe('<br />'.join(links) or '&mdash;')
def value(self, value): 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): 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( a_terminations = CableTerminationsColumn(
cable_end='A', cable_end='A',
accessor=Accessor('terminations'),
orderable=False, orderable=False,
verbose_name='A Side' verbose_name='Termination A'
) )
b_terminations = CableTerminationsColumn( b_terminations = CableTerminationsColumn(
cable_end='B', cable_end='B',
accessor=Accessor('terminations'),
orderable=False, 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() status = columns.ChoiceFieldColumn()
tenant = TenantColumn() tenant = TenantColumn()
@ -82,8 +119,9 @@ class CableTable(NetBoxTable):
class Meta(NetBoxTable.Meta): class Meta(NetBoxTable.Meta):
model = Cable model = Cable
fields = ( fields = (
'pk', 'id', 'label', 'a_terminations', 'b_terminations', 'status', 'type', 'tenant', 'color', 'length', 'pk', 'id', 'label', 'a_terminations', 'b_terminations', 'device_a', 'device_b', 'rack_a', 'rack_b',
'tags', 'created', 'last_updated', 'location_a', 'location_b', 'site_a', 'site_b', 'status', 'type', 'tenant', 'color', 'length', 'tags',
'created', 'last_updated',
) )
default_columns = ( default_columns = (
'pk', 'id', 'label', 'a_terminations', 'b_terminations', 'status', 'type', 'pk', 'id', 'label', 'a_terminations', 'b_terminations', 'status', 'type',

View File

@ -2756,7 +2756,10 @@ class DeviceBulkAddInventoryItemView(generic.BulkComponentCreateView):
# #
class CableListView(generic.ObjectListView): 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 = filtersets.CableFilterSet
filterset_form = forms.CableFilterForm filterset_form = forms.CableFilterForm
table = tables.CableTable table = tables.CableTable