Fixes 17357: Use virtual chassis name as fallback for device (#18710)

This commit is contained in:
Alexander Haase 2025-02-25 16:55:00 +01:00 committed by GitHub
parent 4a4596d5e8
commit bf836c9bc2
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
6 changed files with 46 additions and 15 deletions

View File

@ -1193,6 +1193,7 @@ class DeviceFilterSet(
return queryset
return queryset.filter(
Q(name__icontains=value) |
Q(virtual_chassis__name__icontains=value) |
Q(serial__icontains=value.strip()) |
Q(inventoryitems__serial__icontains=value.strip()) |
Q(asset_tag__icontains=value.strip()) |

View File

@ -802,14 +802,10 @@ class Device(
verbose_name_plural = _('devices')
def __str__(self):
if self.name and self.asset_tag:
return f'{self.name} ({self.asset_tag})'
elif self.name:
return self.name
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})'
if self.label and self.asset_tag:
return f'{self.label} ({self.asset_tag})'
elif self.label:
return self.label
elif self.device_type and self.asset_tag:
return f'{self.device_type.manufacturer} {self.device_type.model} ({self.asset_tag})'
elif self.device_type:
@ -1073,14 +1069,22 @@ class Device(
device.location = self.location
device.save()
@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
def identifier(self):
"""
Return the device name if set; otherwise return the Device's primary key as {pk}
"""
if self.name is not None:
return self.name
return '{{{}}}'.format(self.pk)
return self.label or '{{{}}}'.format(self.pk)
@property
def primary_ip(self):

View File

@ -44,6 +44,7 @@ class DeviceIndex(SearchIndex):
('asset_tag', 50),
('serial', 60),
('name', 100),
('virtual_chassis', 200),
('description', 500),
('comments', 5000),
)

View File

@ -30,10 +30,8 @@ STROKE_RESERVED = '#4d4dff'
def get_device_name(device):
if device.virtual_chassis:
name = f'{device.virtual_chassis.name}:{device.vc_position}'
elif device.name:
name = device.name
if device.label:
name = device.label
else:
name = str(device.device_type)
if device.devicebay_count:

View File

@ -143,6 +143,7 @@ class PlatformTable(NetBoxTable):
class DeviceTable(TenancyColumnsMixin, ContactsColumnMixin, NetBoxTable):
name = tables.TemplateColumn(
verbose_name=_('Name'),
accessor=Accessor('label'),
template_code=DEVICE_LINK,
linkify=True
)

View File

@ -590,6 +590,32 @@ class DeviceTestCase(TestCase):
device2.full_clean()
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)
device1.name = 'Test Device 1'
self.assertEqual(device1.label, 'Test Device 1')
virtual_chassis = VirtualChassis.objects.create(name='VC 1')
device2 = 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(device2.label, 'VC 1:2')
device2.name = 'Test Device 2'
self.assertEqual(device2.label, 'Test Device 2')
def test_device_mismatched_site_cluster(self):
cluster_type = ClusterType.objects.create(name='Cluster Type 1', slug='cluster-type-1')
Cluster.objects.create(name='Cluster 1', type=cluster_type)