From f28bde179e09c1bc0ae10346c393e5f106905d57 Mon Sep 17 00:00:00 2001 From: Jeremy Stretch Date: Thu, 2 Jul 2020 10:46:02 -0400 Subject: [PATCH] Extend label field to all device components --- netbox/dcim/api/serializers.py | 12 +- netbox/dcim/filters.py | 1 + netbox/dcim/forms.py | 120 +++++++----------- .../dcim/migrations/0107_component_labels.py | 51 ++++++-- .../dcim/models/device_component_templates.py | 41 +----- netbox/dcim/models/device_components.py | 76 ++++------- netbox/dcim/tables.py | 5 +- 7 files changed, 119 insertions(+), 187 deletions(-) diff --git a/netbox/dcim/api/serializers.py b/netbox/dcim/api/serializers.py index 6838c3987..3f1eff6a4 100644 --- a/netbox/dcim/api/serializers.py +++ b/netbox/dcim/api/serializers.py @@ -311,7 +311,7 @@ class RearPortTemplateSerializer(ValidatedModelSerializer): class Meta: model = RearPortTemplate - fields = ['id', 'device_type', 'name', 'type', 'positions', 'description'] + fields = ['id', 'device_type', 'name', 'label', 'type', 'positions', 'description'] class FrontPortTemplateSerializer(ValidatedModelSerializer): @@ -321,7 +321,7 @@ class FrontPortTemplateSerializer(ValidatedModelSerializer): class Meta: model = FrontPortTemplate - fields = ['id', 'device_type', 'name', 'type', 'rear_port', 'rear_port_position', 'description'] + fields = ['id', 'device_type', 'name', 'label', 'type', 'rear_port', 'rear_port_position', 'description'] class DeviceBayTemplateSerializer(ValidatedModelSerializer): @@ -559,7 +559,7 @@ class RearPortSerializer(TaggedObjectSerializer, ValidatedModelSerializer): class Meta: model = RearPort - fields = ['id', 'device', 'name', 'type', 'positions', 'description', 'cable', 'tags'] + fields = ['id', 'device', 'name', 'label', 'type', 'positions', 'description', 'cable', 'tags'] class FrontPortRearPortSerializer(WritableNestedSerializer): @@ -570,7 +570,7 @@ class FrontPortRearPortSerializer(WritableNestedSerializer): class Meta: model = RearPort - fields = ['id', 'url', 'name'] + fields = ['id', 'url', 'name', 'label'] class FrontPortSerializer(TaggedObjectSerializer, ValidatedModelSerializer): @@ -581,7 +581,9 @@ class FrontPortSerializer(TaggedObjectSerializer, ValidatedModelSerializer): class Meta: model = FrontPort - fields = ['id', 'device', 'name', 'type', 'rear_port', 'rear_port_position', 'description', 'cable', 'tags'] + fields = [ + 'id', 'device', 'name', 'label', 'type', 'rear_port', 'rear_port_position', 'description', 'cable', 'tags', + ] class DeviceBaySerializer(TaggedObjectSerializer, ValidatedModelSerializer): diff --git a/netbox/dcim/filters.py b/netbox/dcim/filters.py index d22511ede..449a96dcc 100644 --- a/netbox/dcim/filters.py +++ b/netbox/dcim/filters.py @@ -747,6 +747,7 @@ class DeviceComponentFilterSet(django_filters.FilterSet): return queryset return queryset.filter( Q(name__icontains=value) | + Q(label__icontains=value) | Q(description__icontains=value) ) diff --git a/netbox/dcim/forms.py b/netbox/dcim/forms.py index 281818895..65cce8850 100644 --- a/netbox/dcim/forms.py +++ b/netbox/dcim/forms.py @@ -59,7 +59,6 @@ def get_device_by_name_or_pk(name): class DeviceComponentFilterForm(BootstrapMixin, forms.Form): - field_order = [ 'q', 'region', 'site' ] @@ -127,7 +126,11 @@ class InterfaceCommonForm: }) -class LabeledComponentForm(BootstrapMixin, forms.Form): +class ComponentForm(BootstrapMixin, forms.Form): + """ + Subclass this form when facilitating the creation of one or more device component or component templates based on + a name pattern. + """ name_pattern = ExpandableNameField( label='Name' ) @@ -1033,7 +1036,7 @@ class DeviceTypeFilterForm(BootstrapMixin, CustomFieldFilterForm): # Device component templates # -class ComponentTemplateCreateForm(LabeledComponentForm): +class ComponentTemplateCreateForm(ComponentForm): """ Base form for the creation of device component templates. """ @@ -1350,7 +1353,7 @@ class FrontPortTemplateForm(BootstrapMixin, forms.ModelForm): class Meta: model = FrontPortTemplate fields = [ - 'device_type', 'name', 'type', 'rear_port', 'rear_port_position', 'description', + 'device_type', 'name', 'label', 'type', 'rear_port', 'rear_port_position', 'description', ] widgets = { 'device_type': forms.HiddenInput(), @@ -1430,6 +1433,10 @@ class FrontPortTemplateBulkEditForm(BootstrapMixin, BulkEditForm): queryset=FrontPortTemplate.objects.all(), widget=forms.MultipleHiddenInput() ) + label = forms.CharField( + max_length=64, + required=False + ) type = forms.ChoiceField( choices=add_blank_choice(PortTypeChoices), required=False, @@ -1448,7 +1455,7 @@ class RearPortTemplateForm(BootstrapMixin, forms.ModelForm): class Meta: model = RearPortTemplate fields = [ - 'device_type', 'name', 'type', 'positions', 'description', + 'device_type', 'name', 'label', 'type', 'positions', 'description', ] widgets = { 'device_type': forms.HiddenInput(), @@ -1474,6 +1481,10 @@ class RearPortTemplateBulkEditForm(BootstrapMixin, BulkEditForm): queryset=RearPortTemplate.objects.all(), widget=forms.MultipleHiddenInput() ) + label = forms.CharField( + max_length=64, + required=False + ) type = forms.ChoiceField( choices=add_blank_choice(PortTypeChoices), required=False, @@ -2248,7 +2259,7 @@ class DeviceFilterForm(BootstrapMixin, LocalConfigContextFilterForm, TenancyFilt # Device components # -class ComponentCreateForm(LabeledComponentForm): +class ComponentCreateForm(ComponentForm): """ Base form for the creation of device components. """ @@ -2261,7 +2272,7 @@ class ComponentCreateForm(LabeledComponentForm): ) -class DeviceBulkAddComponentForm(LabeledComponentForm): +class DeviceBulkAddComponentForm(ComponentForm): pk = forms.ModelMultipleChoiceField( queryset=Device.objects.all(), widget=forms.MultipleHiddenInput() @@ -3013,7 +3024,7 @@ class FrontPortForm(BootstrapMixin, forms.ModelForm): class Meta: model = FrontPort fields = [ - 'device', 'name', 'type', 'rear_port', 'rear_port_position', 'description', 'tags', + 'device', 'name', 'label', 'type', 'rear_port', 'rear_port_position', 'description', 'tags', ] widgets = { 'device': forms.HiddenInput(), @@ -3094,14 +3105,14 @@ class FrontPortCreateForm(ComponentCreateForm): # class FrontPortBulkCreateForm( -# form_from_model(FrontPort, ['type', 'description', 'tags']), +# form_from_model(FrontPort, ['label', 'type', 'description', 'tags']), # DeviceBulkAddComponentForm # ): # pass class FrontPortBulkEditForm( - form_from_model(FrontPort, ['type', 'description']), + form_from_model(FrontPort, ['label', 'type', 'description']), BootstrapMixin, AddRemoveTagsForm, BulkEditForm @@ -3112,9 +3123,7 @@ class FrontPortBulkEditForm( ) class Meta: - nullable_fields = [ - 'description', - ] + nullable_fields = ('label', 'description') class FrontPortCSVForm(CSVModelForm): @@ -3185,7 +3194,7 @@ class RearPortForm(BootstrapMixin, forms.ModelForm): class Meta: model = RearPort fields = [ - 'device', 'name', 'type', 'positions', 'description', 'tags', + 'device', 'name', 'label', 'type', 'positions', 'description', 'tags', ] widgets = { 'device': forms.HiddenInput(), @@ -3210,14 +3219,14 @@ class RearPortCreateForm(ComponentCreateForm): class RearPortBulkCreateForm( - form_from_model(RearPort, ['type', 'positions', 'description', 'tags']), + form_from_model(RearPort, ['label', 'type', 'positions', 'description', 'tags']), DeviceBulkAddComponentForm ): pass class RearPortBulkEditForm( - form_from_model(RearPort, ['type', 'description']), + form_from_model(RearPort, ['label', 'type', 'description']), BootstrapMixin, AddRemoveTagsForm, BulkEditForm @@ -3228,9 +3237,7 @@ class RearPortBulkEditForm( ) class Meta: - nullable_fields = [ - 'description', - ] + nullable_fields = ('label', 'description') class RearPortCSVForm(CSVModelForm): @@ -3392,17 +3399,11 @@ class InventoryItemForm(BootstrapMixin, forms.ModelForm): class Meta: model = InventoryItem fields = [ - 'name', 'device', 'manufacturer', 'part_id', 'serial', 'asset_tag', 'description', 'tags', + 'name', 'label', 'device', 'manufacturer', 'part_id', 'serial', 'asset_tag', 'description', 'tags', ] -class InventoryItemCreateForm(BootstrapMixin, forms.Form): - device = DynamicModelChoiceField( - queryset=Device.objects.prefetch_related('device_type__manufacturer') - ) - name_pattern = ExpandableNameField( - label='Name' - ) +class InventoryItemCreateForm(ComponentCreateForm): manufacturer = DynamicModelChoiceField( queryset=Manufacturer.objects.all(), required=False @@ -3443,7 +3444,7 @@ class InventoryItemCSVForm(CSVModelForm): class InventoryItemBulkCreateForm( - form_from_model(InventoryItem, ['manufacturer', 'part_id', 'serial', 'asset_tag', 'discovered', 'tags']), + form_from_model(InventoryItem, ['label', 'manufacturer', 'part_id', 'serial', 'asset_tag', 'discovered', 'tags']), DeviceBulkAddComponentForm ): tags = DynamicModelMultipleChoiceField( @@ -3452,68 +3453,27 @@ class InventoryItemBulkCreateForm( ) -class InventoryItemBulkEditForm(BootstrapMixin, BulkEditForm): +class InventoryItemBulkEditForm( + form_from_model(InventoryItem, ['label', 'manufacturer', 'part_id', 'description']), + BootstrapMixin, + AddRemoveTagsForm, + BulkEditForm +): pk = forms.ModelMultipleChoiceField( queryset=InventoryItem.objects.all(), widget=forms.MultipleHiddenInput() ) - device = DynamicModelChoiceField( - queryset=Device.objects.all(), - required=False - ) manufacturer = DynamicModelChoiceField( queryset=Manufacturer.objects.all(), required=False ) - part_id = forms.CharField( - max_length=50, - required=False, - label='Part ID' - ) - description = forms.CharField( - max_length=100, - required=False - ) class Meta: - nullable_fields = [ - 'manufacturer', 'part_id', 'description', - ] + nullable_fields = ('label', 'manufacturer', 'part_id', 'description') -class InventoryItemFilterForm(BootstrapMixin, forms.Form): +class InventoryItemFilterForm(DeviceComponentFilterForm): model = InventoryItem - q = forms.CharField( - required=False, - label='Search' - ) - region = DynamicModelMultipleChoiceField( - queryset=Region.objects.all(), - to_field_name='slug', - required=False, - widget=APISelectMultiple( - value_field="slug", - filter_for={ - 'site': 'region' - } - ) - ) - site = DynamicModelMultipleChoiceField( - queryset=Site.objects.all(), - to_field_name='slug', - required=False, - widget=APISelectMultiple( - value_field="slug", - filter_for={ - 'device_id': 'site' - } - ) - ) - device_id = DynamicModelMultipleChoiceField( - queryset=Device.objects.all(), - required=False, - label='Device' - ) manufacturer = DynamicModelMultipleChoiceField( queryset=Manufacturer.objects.all(), to_field_name='slug', @@ -3522,6 +3482,12 @@ class InventoryItemFilterForm(BootstrapMixin, forms.Form): value_field="slug", ) ) + serial = forms.CharField( + required=False + ) + asset_tag = forms.CharField( + required=False + ) discovered = forms.NullBooleanField( required=False, widget=StaticSelect2( diff --git a/netbox/dcim/migrations/0107_component_labels.py b/netbox/dcim/migrations/0107_component_labels.py index 8e5ab8156..c89bfc0b6 100644 --- a/netbox/dcim/migrations/0107_component_labels.py +++ b/netbox/dcim/migrations/0107_component_labels.py @@ -1,5 +1,3 @@ -# Generated by Django 3.0.7 on 2020-06-04 20:37 - from django.db import migrations, models @@ -10,16 +8,6 @@ class Migration(migrations.Migration): ] operations = [ - migrations.AddField( - model_name='interface', - name='label', - field=models.CharField(blank=True, max_length=64), - ), - migrations.AddField( - model_name='interfacetemplate', - name='label', - field=models.CharField(blank=True, max_length=64), - ), migrations.AddField( model_name='consoleport', name='label', @@ -40,6 +28,41 @@ class Migration(migrations.Migration): name='label', field=models.CharField(blank=True, max_length=64), ), + migrations.AddField( + model_name='devicebay', + name='label', + field=models.CharField(blank=True, max_length=64), + ), + migrations.AddField( + model_name='devicebaytemplate', + name='label', + field=models.CharField(blank=True, max_length=64), + ), + migrations.AddField( + model_name='frontport', + name='label', + field=models.CharField(blank=True, max_length=64), + ), + migrations.AddField( + model_name='frontporttemplate', + name='label', + field=models.CharField(blank=True, max_length=64), + ), + migrations.AddField( + model_name='interface', + name='label', + field=models.CharField(blank=True, max_length=64), + ), + migrations.AddField( + model_name='interfacetemplate', + name='label', + field=models.CharField(blank=True, max_length=64), + ), + migrations.AddField( + model_name='inventoryitem', + name='label', + field=models.CharField(blank=True, max_length=64), + ), migrations.AddField( model_name='poweroutlet', name='label', @@ -61,12 +84,12 @@ class Migration(migrations.Migration): field=models.CharField(blank=True, max_length=64), ), migrations.AddField( - model_name='devicebay', + model_name='rearport', name='label', field=models.CharField(blank=True, max_length=64), ), migrations.AddField( - model_name='devicebaytemplate', + model_name='rearporttemplate', name='label', field=models.CharField(blank=True, max_length=64), ), diff --git a/netbox/dcim/models/device_component_templates.py b/netbox/dcim/models/device_component_templates.py index 1c2be0e5d..626363da1 100644 --- a/netbox/dcim/models/device_component_templates.py +++ b/netbox/dcim/models/device_component_templates.py @@ -27,6 +27,11 @@ __all__ = ( class ComponentTemplateModel(models.Model): + label = models.CharField( + max_length=64, + blank=True, + help_text="Physical label" + ) description = models.CharField( max_length=200, blank=True @@ -81,11 +86,6 @@ class ConsolePortTemplate(ComponentTemplateModel): max_length=100, blank=True ) - label = models.CharField( - max_length=64, - blank=True, - help_text="Physical label" - ) type = models.CharField( max_length=50, choices=ConsolePortTypeChoices, @@ -121,11 +121,6 @@ class ConsoleServerPortTemplate(ComponentTemplateModel): max_length=100, blank=True ) - label = models.CharField( - max_length=64, - blank=True, - help_text="Physical label" - ) type = models.CharField( max_length=50, choices=ConsolePortTypeChoices, @@ -161,11 +156,6 @@ class PowerPortTemplate(ComponentTemplateModel): max_length=100, blank=True ) - label = models.CharField( - max_length=64, - blank=True, - help_text="Physical label" - ) type = models.CharField( max_length=50, choices=PowerPortTypeChoices, @@ -215,11 +205,6 @@ class PowerOutletTemplate(ComponentTemplateModel): max_length=100, blank=True ) - label = models.CharField( - max_length=64, - blank=True, - help_text="Physical label" - ) type = models.CharField( max_length=50, choices=PowerOutletTypeChoices, @@ -283,11 +268,6 @@ class InterfaceTemplate(ComponentTemplateModel): max_length=100, blank=True ) - label = models.CharField( - max_length=64, - blank=True, - help_text="Physical label" - ) type = models.CharField( max_length=50, choices=InterfaceTypeChoices @@ -348,9 +328,6 @@ class FrontPortTemplate(ComponentTemplateModel): ('rear_port', 'rear_port_position'), ) - def __str__(self): - return self.name - def clean(self): # Validate rear port assignment @@ -411,9 +388,6 @@ class RearPortTemplate(ComponentTemplateModel): ordering = ('device_type', '_name') unique_together = ('device_type', 'name') - def __str__(self): - return self.name - def instantiate(self, device): return RearPort( device=device, @@ -440,11 +414,6 @@ class DeviceBayTemplate(ComponentTemplateModel): max_length=100, blank=True ) - label = models.CharField( - max_length=64, - blank=True, - help_text="Physical label" - ) class Meta: ordering = ('device_type', '_name') diff --git a/netbox/dcim/models/device_components.py b/netbox/dcim/models/device_components.py index aecf57544..aea34e73e 100644 --- a/netbox/dcim/models/device_components.py +++ b/netbox/dcim/models/device_components.py @@ -36,6 +36,11 @@ __all__ = ( class ComponentModel(models.Model): + label = models.CharField( + max_length=64, + blank=True, + help_text="Physical label" + ) description = models.CharField( max_length=200, blank=True @@ -241,11 +246,6 @@ class ConsolePort(CableTermination, ComponentModel): name = models.CharField( max_length=50 ) - label = models.CharField( - max_length=64, - blank=True, - help_text="Physical label" - ) _name = NaturalOrderingField( target_field='name', max_length=100, @@ -270,7 +270,7 @@ class ConsolePort(CableTermination, ComponentModel): ) tags = TaggableManager(through=TaggedItem) - csv_headers = ['device', 'name', 'type', 'description'] + csv_headers = ['device', 'name', 'label', 'type', 'description'] class Meta: ordering = ('device', '_name') @@ -283,6 +283,7 @@ class ConsolePort(CableTermination, ComponentModel): return ( self.device.identifier, self.name, + self.label, self.type, self.description, ) @@ -310,11 +311,6 @@ class ConsoleServerPort(CableTermination, ComponentModel): max_length=100, blank=True ) - label = models.CharField( - max_length=64, - blank=True, - help_text="Physical label" - ) type = models.CharField( max_length=50, choices=ConsolePortTypeChoices, @@ -327,7 +323,7 @@ class ConsoleServerPort(CableTermination, ComponentModel): ) tags = TaggableManager(through=TaggedItem) - csv_headers = ['device', 'name', 'type', 'description'] + csv_headers = ['device', 'name', 'label', 'type', 'description'] class Meta: ordering = ('device', '_name') @@ -340,6 +336,7 @@ class ConsoleServerPort(CableTermination, ComponentModel): return ( self.device.identifier, self.name, + self.label, self.type, self.description, ) @@ -367,11 +364,6 @@ class PowerPort(CableTermination, ComponentModel): max_length=100, blank=True ) - label = models.CharField( - max_length=64, - blank=True, - help_text="Physical label" - ) type = models.CharField( max_length=50, choices=PowerPortTypeChoices, @@ -410,7 +402,7 @@ class PowerPort(CableTermination, ComponentModel): ) tags = TaggableManager(through=TaggedItem) - csv_headers = ['device', 'name', 'type', 'maximum_draw', 'allocated_draw', 'description'] + csv_headers = ['device', 'name', 'label', 'type', 'maximum_draw', 'allocated_draw', 'description'] class Meta: ordering = ('device', '_name') @@ -423,6 +415,7 @@ class PowerPort(CableTermination, ComponentModel): return ( self.device.identifier, self.name, + self.label, self.get_type_display(), self.maximum_draw, self.allocated_draw, @@ -532,11 +525,6 @@ class PowerOutlet(CableTermination, ComponentModel): max_length=100, blank=True ) - label = models.CharField( - max_length=64, - blank=True, - help_text="Physical label" - ) type = models.CharField( max_length=50, choices=PowerOutletTypeChoices, @@ -562,7 +550,7 @@ class PowerOutlet(CableTermination, ComponentModel): ) tags = TaggableManager(through=TaggedItem) - csv_headers = ['device', 'name', 'type', 'power_port', 'feed_leg', 'description'] + csv_headers = ['device', 'name', 'label', 'type', 'power_port', 'feed_leg', 'description'] class Meta: ordering = ('device', '_name') @@ -575,6 +563,7 @@ class PowerOutlet(CableTermination, ComponentModel): return ( self.device.identifier, self.name, + self.label, self.get_type_display(), self.power_port.name if self.power_port else None, self.get_feed_leg_display(), @@ -640,11 +629,6 @@ class Interface(CableTermination, ComponentModel, BaseInterface): null=True, blank=True ) - label = models.CharField( - max_length=64, - blank=True, - help_text="Physical label" - ) _connected_interface = models.OneToOneField( to='self', on_delete=models.SET_NULL, @@ -703,7 +687,7 @@ class Interface(CableTermination, ComponentModel, BaseInterface): tags = TaggableManager(through=TaggedItem) csv_headers = [ - 'device', 'name', 'lag', 'type', 'enabled', 'mac_address', 'mtu', 'mgmt_only', 'description', 'mode', + 'device', 'name', 'label', 'lag', 'type', 'enabled', 'mac_address', 'mtu', 'mgmt_only', 'description', 'mode', ] class Meta: @@ -717,6 +701,7 @@ class Interface(CableTermination, ComponentModel, BaseInterface): return ( self.device.identifier if self.device else None, self.name, + self.label, self.lag.name if self.lag else None, self.get_type_display(), self.enabled, @@ -877,7 +862,7 @@ class FrontPort(CableTermination, ComponentModel): ) tags = TaggableManager(through=TaggedItem) - csv_headers = ['device', 'name', 'type', 'rear_port', 'rear_port_position', 'description'] + csv_headers = ['device', 'name', 'label', 'type', 'rear_port', 'rear_port_position', 'description'] class Meta: ordering = ('device', '_name') @@ -886,9 +871,6 @@ class FrontPort(CableTermination, ComponentModel): ('rear_port', 'rear_port_position'), ) - def __str__(self): - return self.name - def get_absolute_url(self): return reverse('dcim:frontport', kwargs={'pk': self.pk}) @@ -896,6 +878,7 @@ class FrontPort(CableTermination, ComponentModel): return ( self.device.identifier, self.name, + self.label, self.get_type_display(), self.rear_port.name, self.rear_port_position, @@ -947,15 +930,12 @@ class RearPort(CableTermination, ComponentModel): ) tags = TaggableManager(through=TaggedItem) - csv_headers = ['device', 'name', 'type', 'positions', 'description'] + csv_headers = ['device', 'name', 'label', 'type', 'positions', 'description'] class Meta: ordering = ('device', '_name') unique_together = ('device', 'name') - def __str__(self): - return self.name - def get_absolute_url(self): return reverse('dcim:rearport', kwargs={'pk': self.pk}) @@ -963,6 +943,7 @@ class RearPort(CableTermination, ComponentModel): return ( self.device.identifier, self.name, + self.label, self.get_type_display(), self.positions, self.description, @@ -992,11 +973,6 @@ class DeviceBay(ComponentModel): max_length=100, blank=True ) - label = models.CharField( - max_length=64, - blank=True, - help_text="Physical label" - ) installed_device = models.OneToOneField( to='dcim.Device', on_delete=models.SET_NULL, @@ -1006,17 +982,12 @@ class DeviceBay(ComponentModel): ) tags = TaggableManager(through=TaggedItem) - csv_headers = ['device', 'name', 'installed_device', 'description'] + csv_headers = ['device', 'name', 'label', 'installed_device', 'description'] class Meta: ordering = ('device', '_name') unique_together = ('device', 'name') - def __str__(self): - if self.label: - return '{} - {} ({})'.format(self.device.name, self.name, self.label) - return '{} - {}'.format(self.device.name, self.name) - def get_absolute_url(self): return reverse('dcim:devicebay', kwargs={'pk': self.pk}) @@ -1024,6 +995,7 @@ class DeviceBay(ComponentModel): return ( self.device.identifier, self.name, + self.label, self.installed_device.identifier if self.installed_device else None, self.description, ) @@ -1116,16 +1088,13 @@ class InventoryItem(ComponentModel): tags = TaggableManager(through=TaggedItem) csv_headers = [ - 'device', 'name', 'manufacturer', 'part_id', 'serial', 'asset_tag', 'discovered', 'description', + 'device', 'name', 'label', 'manufacturer', 'part_id', 'serial', 'asset_tag', 'discovered', 'description', ] class Meta: ordering = ('device__id', 'parent__id', '_name') unique_together = ('device', 'parent', 'name') - def __str__(self): - return self.name - def get_absolute_url(self): return reverse('dcim:inventoryitem', kwargs={'pk': self.pk}) @@ -1133,6 +1102,7 @@ class InventoryItem(ComponentModel): return ( self.device.name or '{{{}}}'.format(self.device.pk), self.name, + self.label, self.manufacturer.name if self.manufacturer else None, self.part_id, self.serial, diff --git a/netbox/dcim/tables.py b/netbox/dcim/tables.py index f258df221..587749277 100644 --- a/netbox/dcim/tables.py +++ b/netbox/dcim/tables.py @@ -784,9 +784,10 @@ class InventoryItemTable(DeviceComponentTable): class Meta(DeviceComponentTable.Meta): model = InventoryItem fields = ( - 'pk', 'device', 'name', 'manufacturer', 'part_id', 'serial', 'asset_tag', 'description', 'discovered' + 'pk', 'device', 'name', 'label', 'manufacturer', 'part_id', 'serial', 'asset_tag', 'description', + 'discovered', ) - default_columns = ('pk', 'device', 'name', 'manufacturer', 'part_id', 'serial', 'asset_tag') + default_columns = ('pk', 'device', 'name', 'label', 'manufacturer', 'part_id', 'serial', 'asset_tag') #