From aee885c82285532de7f948df46b711f73cc9b3b1 Mon Sep 17 00:00:00 2001 From: Elliott Balsley <3991046+llamafilm@users.noreply.github.com> Date: Fri, 8 Aug 2025 00:18:13 -0700 Subject: [PATCH 1/7] add columns for site, location, description, serial, type --- netbox/dcim/tables/devices.py | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/netbox/dcim/tables/devices.py b/netbox/dcim/tables/devices.py index f0465a1b539..a22d560f80c 100644 --- a/netbox/dcim/tables/devices.py +++ b/netbox/dcim/tables/devices.py @@ -303,11 +303,34 @@ class DeviceComponentTable(NetBoxTable): verbose_name=_('Name'), linkify=True, ) + device_description = tables.Column( + accessor=tables.A('device__description'), + verbose_name=_('Device Description'), + ) + device_location = tables.Column( + accessor=tables.A('device__location'), + verbose_name=_('Device Location'), + linkify=True, + ) + device_serial = tables.Column( + accessor=tables.A('device__serial'), + verbose_name=_('Device Serial'), + ) + device_site = tables.Column( + accessor=tables.A('device__site'), + verbose_name=_('Device Site'), + linkify=True, + ) device_status = columns.ChoiceFieldColumn( accessor=tables.A('device__status'), verbose_name=_('Device Status'), color=lambda x: x.device.get_status_color(), ) + device_type = tables.Column( + accessor=tables.A('device__device_type'), + verbose_name=_('Device Type'), + linkify=True, + ) class Meta(NetBoxTable.Meta): order_by = ('device', 'name') From 94a9a943c3a7fe20c9614635b90790d51c085189 Mon Sep 17 00:00:00 2001 From: Elliott Balsley <3991046+llamafilm@users.noreply.github.com> Date: Fri, 8 Aug 2025 00:20:34 -0700 Subject: [PATCH 2/7] add device custom fields --- netbox/dcim/tables/devices.py | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/netbox/dcim/tables/devices.py b/netbox/dcim/tables/devices.py index a22d560f80c..8da162782bc 100644 --- a/netbox/dcim/tables/devices.py +++ b/netbox/dcim/tables/devices.py @@ -2,7 +2,10 @@ from django.utils.translation import gettext_lazy as _ from django_tables2.utils import Accessor +from core.models import ObjectType from dcim import models +from extras.choices import CustomFieldUIVisibleChoices +from extras.models import CustomField from netbox.tables import NetBoxTable, columns from tenancy.tables import ContactsColumnMixin, TenancyColumnsMixin from .template_code import * @@ -332,6 +335,25 @@ class DeviceComponentTable(NetBoxTable): linkify=True, ) + def __init__(self, *args, extra_columns=None, **kwargs): + if extra_columns is None: + extra_columns = [] + + # Add columns for each Device custom field + device_object_type = ObjectType.objects.get_for_model(models.Device) + device_custom_fields = CustomField.objects.filter( + object_types=device_object_type + ).exclude(ui_visible=CustomFieldUIVisibleChoices.HIDDEN) + + for cf in device_custom_fields: + # override accessor for device relationship + column = columns.CustomFieldColumn(cf) + column.accessor = tables.A(f'device__custom_field_data__{cf.name}') + column.verbose_name = f'Device {cf.label or cf.name}' + extra_columns.append((f'device_cf_{cf.name}', column)) + + super().__init__(*args, extra_columns=extra_columns, **kwargs) + class Meta(NetBoxTable.Meta): order_by = ('device', 'name') From 19684898b13671852fd6151f17505018ab323e48 Mon Sep 17 00:00:00 2001 From: Elliott Balsley <3991046+llamafilm@users.noreply.github.com> Date: Sat, 30 Aug 2025 01:00:49 -0700 Subject: [PATCH 3/7] add installed_device__description to DeviceBayTable --- netbox/dcim/tables/devices.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/netbox/dcim/tables/devices.py b/netbox/dcim/tables/devices.py index 8da162782bc..157f47c710d 100644 --- a/netbox/dcim/tables/devices.py +++ b/netbox/dcim/tables/devices.py @@ -909,6 +909,10 @@ class DeviceBayTable(DeviceComponentTable): verbose_name=_('Installed device'), linkify=True ) + device_description = tables.Column( + accessor=Accessor('installed_device__description'), + verbose_name=_('Device Description'), + ) tags = columns.TagColumn( url_name='dcim:devicebay_list' ) From 47390742f617e81f0a1d5f541a16db2e782efdc2 Mon Sep 17 00:00:00 2001 From: Elliott Balsley <3991046+llamafilm@users.noreply.github.com> Date: Fri, 12 Sep 2025 12:55:21 -0700 Subject: [PATCH 4/7] add Contacts and custom fields for related Location --- netbox/dcim/tables/devices.py | 21 ++++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) diff --git a/netbox/dcim/tables/devices.py b/netbox/dcim/tables/devices.py index f68af312083..dad098daf91 100644 --- a/netbox/dcim/tables/devices.py +++ b/netbox/dcim/tables/devices.py @@ -338,6 +338,12 @@ class DeviceComponentTable(NetBoxTable): verbose_name=_('Device Type'), linkify=True, ) + location_contacts = columns.ManyToManyColumn( + accessor=tables.A('device__location__contacts'), + verbose_name=_('Location Contacts'), + linkify_item=True, + transform=lambda obj: obj.contact.name + ) def __init__(self, *args, extra_columns=None, **kwargs): if extra_columns is None: @@ -348,14 +354,23 @@ def __init__(self, *args, extra_columns=None, **kwargs): device_custom_fields = CustomField.objects.filter( object_types=device_object_type ).exclude(ui_visible=CustomFieldUIVisibleChoices.HIDDEN) - for cf in device_custom_fields: - # override accessor for device relationship column = columns.CustomFieldColumn(cf) column.accessor = tables.A(f'device__custom_field_data__{cf.name}') - column.verbose_name = f'Device {cf.label or cf.name}' + column.verbose_name = f'Device: {cf.label or cf.name}' extra_columns.append((f'device_cf_{cf.name}', column)) + # Add columns for each Location custom field + location_object_type = ObjectType.objects.get_for_model(models.Location) + location_custom_fields = CustomField.objects.filter( + object_types=location_object_type + ).exclude(ui_visible=CustomFieldUIVisibleChoices.HIDDEN) + for cf in location_custom_fields: + column = columns.CustomFieldColumn(cf) + column.accessor = tables.A(f'device__location__custom_field_data__{cf.name}') + column.verbose_name = f'Location: {cf.label or cf.name}' + extra_columns.append((f'location_cf_{cf.name}', column)) + super().__init__(*args, extra_columns=extra_columns, **kwargs) class Meta(NetBoxTable.Meta): From a36f2c189f5c86b167dd6ae223f401f28b398958 Mon Sep 17 00:00:00 2001 From: Elliott Balsley <3991046+llamafilm@users.noreply.github.com> Date: Fri, 12 Sep 2025 13:50:59 -0700 Subject: [PATCH 5/7] rename Installed Device Description --- netbox/dcim/tables/devices.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/netbox/dcim/tables/devices.py b/netbox/dcim/tables/devices.py index dad098daf91..bf506d653c6 100644 --- a/netbox/dcim/tables/devices.py +++ b/netbox/dcim/tables/devices.py @@ -928,9 +928,9 @@ class DeviceBayTable(DeviceComponentTable): verbose_name=_('Installed device'), linkify=True ) - device_description = tables.Column( + installed_device_description = tables.Column( accessor=Accessor('installed_device__description'), - verbose_name=_('Device Description'), + verbose_name=_('Installed Device Description'), ) tags = columns.TagColumn( url_name='dcim:devicebay_list' From d2d25814cb9800dce5b193e01551c1864480ab3c Mon Sep 17 00:00:00 2001 From: Elliott Balsley <3991046+llamafilm@users.noreply.github.com> Date: Tue, 23 Sep 2025 18:24:50 -0700 Subject: [PATCH 6/7] remove extra columns --- netbox/dcim/tables/devices.py | 51 ----------------------------------- 1 file changed, 51 deletions(-) diff --git a/netbox/dcim/tables/devices.py b/netbox/dcim/tables/devices.py index bf506d653c6..bf2a3b9f0c8 100644 --- a/netbox/dcim/tables/devices.py +++ b/netbox/dcim/tables/devices.py @@ -310,19 +310,11 @@ class DeviceComponentTable(NetBoxTable): verbose_name=_('Name'), linkify=True, ) - device_description = tables.Column( - accessor=tables.A('device__description'), - verbose_name=_('Device Description'), - ) device_location = tables.Column( accessor=tables.A('device__location'), verbose_name=_('Device Location'), linkify=True, ) - device_serial = tables.Column( - accessor=tables.A('device__serial'), - verbose_name=_('Device Serial'), - ) device_site = tables.Column( accessor=tables.A('device__site'), verbose_name=_('Device Site'), @@ -333,45 +325,6 @@ class DeviceComponentTable(NetBoxTable): verbose_name=_('Device Status'), color=lambda x: x.device.get_status_color(), ) - device_type = tables.Column( - accessor=tables.A('device__device_type'), - verbose_name=_('Device Type'), - linkify=True, - ) - location_contacts = columns.ManyToManyColumn( - accessor=tables.A('device__location__contacts'), - verbose_name=_('Location Contacts'), - linkify_item=True, - transform=lambda obj: obj.contact.name - ) - - def __init__(self, *args, extra_columns=None, **kwargs): - if extra_columns is None: - extra_columns = [] - - # Add columns for each Device custom field - device_object_type = ObjectType.objects.get_for_model(models.Device) - device_custom_fields = CustomField.objects.filter( - object_types=device_object_type - ).exclude(ui_visible=CustomFieldUIVisibleChoices.HIDDEN) - for cf in device_custom_fields: - column = columns.CustomFieldColumn(cf) - column.accessor = tables.A(f'device__custom_field_data__{cf.name}') - column.verbose_name = f'Device: {cf.label or cf.name}' - extra_columns.append((f'device_cf_{cf.name}', column)) - - # Add columns for each Location custom field - location_object_type = ObjectType.objects.get_for_model(models.Location) - location_custom_fields = CustomField.objects.filter( - object_types=location_object_type - ).exclude(ui_visible=CustomFieldUIVisibleChoices.HIDDEN) - for cf in location_custom_fields: - column = columns.CustomFieldColumn(cf) - column.accessor = tables.A(f'device__location__custom_field_data__{cf.name}') - column.verbose_name = f'Location: {cf.label or cf.name}' - extra_columns.append((f'location_cf_{cf.name}', column)) - - super().__init__(*args, extra_columns=extra_columns, **kwargs) class Meta(NetBoxTable.Meta): order_by = ('device', 'name') @@ -928,10 +881,6 @@ class DeviceBayTable(DeviceComponentTable): verbose_name=_('Installed device'), linkify=True ) - installed_device_description = tables.Column( - accessor=Accessor('installed_device__description'), - verbose_name=_('Installed Device Description'), - ) tags = columns.TagColumn( url_name='dcim:devicebay_list' ) From 63a0e12bdc2eb585eeb125d35bee30adc6c6ad96 Mon Sep 17 00:00:00 2001 From: Elliott Balsley <3991046+llamafilm@users.noreply.github.com> Date: Tue, 23 Sep 2025 18:26:05 -0700 Subject: [PATCH 7/7] remove unused imports --- netbox/dcim/tables/devices.py | 3 --- 1 file changed, 3 deletions(-) diff --git a/netbox/dcim/tables/devices.py b/netbox/dcim/tables/devices.py index bf2a3b9f0c8..a52e49df4b3 100644 --- a/netbox/dcim/tables/devices.py +++ b/netbox/dcim/tables/devices.py @@ -2,10 +2,7 @@ from django.utils.translation import gettext_lazy as _ from django_tables2.utils import Accessor -from core.models import ObjectType from dcim import models -from extras.choices import CustomFieldUIVisibleChoices -from extras.models import CustomField from netbox.tables import NetBoxTable, columns from tenancy.tables import ContactsColumnMixin, TenancyColumnsMixin from .template_code import *