Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions netbox/dcim/filtersets.py
Original file line number Diff line number Diff line change
Expand Up @@ -1193,6 +1193,7 @@ def search(self, queryset, name, value):
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()) |
Expand Down
26 changes: 15 additions & 11 deletions netbox/dcim/models/devices.py
Original file line number Diff line number Diff line change
Expand Up @@ -802,14 +802,10 @@ class Meta:
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:
Expand Down Expand Up @@ -1073,14 +1069,22 @@ def save(self, *args, **kwargs):
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):
Expand Down
1 change: 1 addition & 0 deletions netbox/dcim/search.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ class DeviceIndex(SearchIndex):
('asset_tag', 50),
('serial', 60),
('name', 100),
('virtual_chassis', 200),
('description', 500),
('comments', 5000),
)
Expand Down
6 changes: 2 additions & 4 deletions netbox/dcim/svg/racks.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,10 +30,8 @@


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:
Expand Down
1 change: 1 addition & 0 deletions netbox/dcim/tables/devices.py
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,7 @@ class Meta(NetBoxTable.Meta):
class DeviceTable(TenancyColumnsMixin, ContactsColumnMixin, NetBoxTable):
name = tables.TemplateColumn(
verbose_name=_('Name'),
accessor=Accessor('label'),
template_code=DEVICE_LINK,
linkify=True
)
Expand Down
26 changes: 26 additions & 0 deletions netbox/dcim/tests/test_models.py
Original file line number Diff line number Diff line change
Expand Up @@ -590,6 +590,32 @@ def test_device_duplicate_names(self):
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)
Expand Down