mirror of
https://github.com/netbox-community/netbox.git
synced 2025-07-27 19:08:38 -06:00
Enhance display name of devices
If a name is not defined for a device, it is automatically generated from other device data (i.e. virtual chassis member) if possible. This name is available as 'label' attribute to not interfere with existing functionality or break APIs.
This commit is contained in:
parent
b02bf77888
commit
2b7c425b57
@ -802,14 +802,10 @@ class Device(
|
|||||||
verbose_name_plural = _('devices')
|
verbose_name_plural = _('devices')
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
if self.name and self.asset_tag:
|
if self.label and self.asset_tag:
|
||||||
return f'{self.name} ({self.asset_tag})'
|
return f'{self.label} ({self.asset_tag})'
|
||||||
elif self.name:
|
elif self.label:
|
||||||
return self.name
|
return self.label
|
||||||
elif self.virtual_chassis and self.asset_tag:
|
|
||||||
return f'{self.virtual_chassis.name}:{self.vc_position} ({self.asset_tag})'
|
|
||||||
elif self.virtual_chassis:
|
|
||||||
return f'{self.virtual_chassis.name}:{self.vc_position} ({self.pk})'
|
|
||||||
elif self.device_type and self.asset_tag:
|
elif self.device_type and self.asset_tag:
|
||||||
return f'{self.device_type.manufacturer} {self.device_type.model} ({self.asset_tag})'
|
return f'{self.device_type.manufacturer} {self.device_type.model} ({self.asset_tag})'
|
||||||
elif self.device_type:
|
elif self.device_type:
|
||||||
@ -1073,14 +1069,22 @@ class Device(
|
|||||||
device.location = self.location
|
device.location = self.location
|
||||||
device.save()
|
device.save()
|
||||||
|
|
||||||
|
@cached_property
|
||||||
|
def label(self):
|
||||||
|
"""
|
||||||
|
Return the device name if set; otherwise return a generated name if available.
|
||||||
|
"""
|
||||||
|
if self.name:
|
||||||
|
return self.name
|
||||||
|
if self.virtual_chassis:
|
||||||
|
return f'{self.virtual_chassis.name}:{self.vc_position}'
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def identifier(self):
|
def identifier(self):
|
||||||
"""
|
"""
|
||||||
Return the device name if set; otherwise return the Device's primary key as {pk}
|
Return the device name if set; otherwise return the Device's primary key as {pk}
|
||||||
"""
|
"""
|
||||||
if self.name is not None:
|
return self.label or '{{{}}}'.format(self.pk)
|
||||||
return self.name
|
|
||||||
return '{{{}}}'.format(self.pk)
|
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def primary_ip(self):
|
def primary_ip(self):
|
||||||
|
@ -30,10 +30,8 @@ STROKE_RESERVED = '#4d4dff'
|
|||||||
|
|
||||||
|
|
||||||
def get_device_name(device):
|
def get_device_name(device):
|
||||||
if device.virtual_chassis:
|
if device.label:
|
||||||
name = f'{device.virtual_chassis.name}:{device.vc_position}'
|
name = device.label
|
||||||
elif device.name:
|
|
||||||
name = device.name
|
|
||||||
else:
|
else:
|
||||||
name = str(device.device_type)
|
name = str(device.device_type)
|
||||||
if device.devicebay_count:
|
if device.devicebay_count:
|
||||||
|
@ -143,6 +143,7 @@ class PlatformTable(NetBoxTable):
|
|||||||
class DeviceTable(TenancyColumnsMixin, ContactsColumnMixin, NetBoxTable):
|
class DeviceTable(TenancyColumnsMixin, ContactsColumnMixin, NetBoxTable):
|
||||||
name = tables.TemplateColumn(
|
name = tables.TemplateColumn(
|
||||||
verbose_name=_('Name'),
|
verbose_name=_('Name'),
|
||||||
|
accessor=Accessor('label'),
|
||||||
template_code=DEVICE_LINK,
|
template_code=DEVICE_LINK,
|
||||||
linkify=True
|
linkify=True
|
||||||
)
|
)
|
||||||
|
@ -590,6 +590,34 @@ class DeviceTestCase(TestCase):
|
|||||||
device2.full_clean()
|
device2.full_clean()
|
||||||
device2.save()
|
device2.save()
|
||||||
|
|
||||||
|
def test_device_label(self):
|
||||||
|
device1 = Device(
|
||||||
|
site=Site.objects.first(),
|
||||||
|
device_type=DeviceType.objects.first(),
|
||||||
|
role=DeviceRole.objects.first(),
|
||||||
|
name=None,
|
||||||
|
)
|
||||||
|
self.assertEqual(device1.label, None)
|
||||||
|
|
||||||
|
device2 = Device(
|
||||||
|
site=Site.objects.first(),
|
||||||
|
device_type=DeviceType.objects.first(),
|
||||||
|
role=DeviceRole.objects.first(),
|
||||||
|
name='Test Device 2',
|
||||||
|
)
|
||||||
|
self.assertEqual(device2.label, 'Test Device 2')
|
||||||
|
|
||||||
|
virtual_chassis = VirtualChassis.objects.create(name='VC 1')
|
||||||
|
device3 = Device(
|
||||||
|
site=Site.objects.first(),
|
||||||
|
device_type=DeviceType.objects.first(),
|
||||||
|
role=DeviceRole.objects.first(),
|
||||||
|
name=None,
|
||||||
|
virtual_chassis=virtual_chassis,
|
||||||
|
vc_position=2,
|
||||||
|
)
|
||||||
|
self.assertEqual(device3.label, 'VC 1:2')
|
||||||
|
|
||||||
def test_device_mismatched_site_cluster(self):
|
def test_device_mismatched_site_cluster(self):
|
||||||
cluster_type = ClusterType.objects.create(name='Cluster Type 1', slug='cluster-type-1')
|
cluster_type = ClusterType.objects.create(name='Cluster Type 1', slug='cluster-type-1')
|
||||||
Cluster.objects.create(name='Cluster 1', type=cluster_type)
|
Cluster.objects.create(name='Cluster 1', type=cluster_type)
|
||||||
|
Loading…
Reference in New Issue
Block a user