Просмотр исходного кода

Extend label field to all device components

Jeremy Stretch 5 лет назад
Родитель
Сommit
f28bde179e

+ 7 - 5
netbox/dcim/api/serializers.py

@@ -311,7 +311,7 @@ class RearPortTemplateSerializer(ValidatedModelSerializer):
 
 
     class Meta:
     class Meta:
         model = RearPortTemplate
         model = RearPortTemplate
-        fields = ['id', 'device_type', 'name', 'type', 'positions', 'description']
+        fields = ['id', 'device_type', 'name', 'label', 'type', 'positions', 'description']
 
 
 
 
 class FrontPortTemplateSerializer(ValidatedModelSerializer):
 class FrontPortTemplateSerializer(ValidatedModelSerializer):
@@ -321,7 +321,7 @@ class FrontPortTemplateSerializer(ValidatedModelSerializer):
 
 
     class Meta:
     class Meta:
         model = FrontPortTemplate
         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):
 class DeviceBayTemplateSerializer(ValidatedModelSerializer):
@@ -559,7 +559,7 @@ class RearPortSerializer(TaggedObjectSerializer, ValidatedModelSerializer):
 
 
     class Meta:
     class Meta:
         model = RearPort
         model = RearPort
-        fields = ['id', 'device', 'name', 'type', 'positions', 'description', 'cable', 'tags']
+        fields = ['id', 'device', 'name', 'label', 'type', 'positions', 'description', 'cable', 'tags']
 
 
 
 
 class FrontPortRearPortSerializer(WritableNestedSerializer):
 class FrontPortRearPortSerializer(WritableNestedSerializer):
@@ -570,7 +570,7 @@ class FrontPortRearPortSerializer(WritableNestedSerializer):
 
 
     class Meta:
     class Meta:
         model = RearPort
         model = RearPort
-        fields = ['id', 'url', 'name']
+        fields = ['id', 'url', 'name', 'label']
 
 
 
 
 class FrontPortSerializer(TaggedObjectSerializer, ValidatedModelSerializer):
 class FrontPortSerializer(TaggedObjectSerializer, ValidatedModelSerializer):
@@ -581,7 +581,9 @@ class FrontPortSerializer(TaggedObjectSerializer, ValidatedModelSerializer):
 
 
     class Meta:
     class Meta:
         model = FrontPort
         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):
 class DeviceBaySerializer(TaggedObjectSerializer, ValidatedModelSerializer):

+ 1 - 0
netbox/dcim/filters.py

@@ -747,6 +747,7 @@ class DeviceComponentFilterSet(django_filters.FilterSet):
             return queryset
             return queryset
         return queryset.filter(
         return queryset.filter(
             Q(name__icontains=value) |
             Q(name__icontains=value) |
+            Q(label__icontains=value) |
             Q(description__icontains=value)
             Q(description__icontains=value)
         )
         )
 
 

+ 43 - 77
netbox/dcim/forms.py

@@ -59,7 +59,6 @@ def get_device_by_name_or_pk(name):
 
 
 
 
 class DeviceComponentFilterForm(BootstrapMixin, forms.Form):
 class DeviceComponentFilterForm(BootstrapMixin, forms.Form):
-
     field_order = [
     field_order = [
         'q', 'region', 'site'
         '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(
     name_pattern = ExpandableNameField(
         label='Name'
         label='Name'
     )
     )
@@ -1033,7 +1036,7 @@ class DeviceTypeFilterForm(BootstrapMixin, CustomFieldFilterForm):
 # Device component templates
 # Device component templates
 #
 #
 
 
-class ComponentTemplateCreateForm(LabeledComponentForm):
+class ComponentTemplateCreateForm(ComponentForm):
     """
     """
     Base form for the creation of device component templates.
     Base form for the creation of device component templates.
     """
     """
@@ -1350,7 +1353,7 @@ class FrontPortTemplateForm(BootstrapMixin, forms.ModelForm):
     class Meta:
     class Meta:
         model = FrontPortTemplate
         model = FrontPortTemplate
         fields = [
         fields = [
-            'device_type', 'name', 'type', 'rear_port', 'rear_port_position', 'description',
+            'device_type', 'name', 'label', 'type', 'rear_port', 'rear_port_position', 'description',
         ]
         ]
         widgets = {
         widgets = {
             'device_type': forms.HiddenInput(),
             'device_type': forms.HiddenInput(),
@@ -1430,6 +1433,10 @@ class FrontPortTemplateBulkEditForm(BootstrapMixin, BulkEditForm):
         queryset=FrontPortTemplate.objects.all(),
         queryset=FrontPortTemplate.objects.all(),
         widget=forms.MultipleHiddenInput()
         widget=forms.MultipleHiddenInput()
     )
     )
+    label = forms.CharField(
+        max_length=64,
+        required=False
+    )
     type = forms.ChoiceField(
     type = forms.ChoiceField(
         choices=add_blank_choice(PortTypeChoices),
         choices=add_blank_choice(PortTypeChoices),
         required=False,
         required=False,
@@ -1448,7 +1455,7 @@ class RearPortTemplateForm(BootstrapMixin, forms.ModelForm):
     class Meta:
     class Meta:
         model = RearPortTemplate
         model = RearPortTemplate
         fields = [
         fields = [
-            'device_type', 'name', 'type', 'positions', 'description',
+            'device_type', 'name', 'label', 'type', 'positions', 'description',
         ]
         ]
         widgets = {
         widgets = {
             'device_type': forms.HiddenInput(),
             'device_type': forms.HiddenInput(),
@@ -1474,6 +1481,10 @@ class RearPortTemplateBulkEditForm(BootstrapMixin, BulkEditForm):
         queryset=RearPortTemplate.objects.all(),
         queryset=RearPortTemplate.objects.all(),
         widget=forms.MultipleHiddenInput()
         widget=forms.MultipleHiddenInput()
     )
     )
+    label = forms.CharField(
+        max_length=64,
+        required=False
+    )
     type = forms.ChoiceField(
     type = forms.ChoiceField(
         choices=add_blank_choice(PortTypeChoices),
         choices=add_blank_choice(PortTypeChoices),
         required=False,
         required=False,
@@ -2248,7 +2259,7 @@ class DeviceFilterForm(BootstrapMixin, LocalConfigContextFilterForm, TenancyFilt
 # Device components
 # Device components
 #
 #
 
 
-class ComponentCreateForm(LabeledComponentForm):
+class ComponentCreateForm(ComponentForm):
     """
     """
     Base form for the creation of device components.
     Base form for the creation of device components.
     """
     """
@@ -2261,7 +2272,7 @@ class ComponentCreateForm(LabeledComponentForm):
     )
     )
 
 
 
 
-class DeviceBulkAddComponentForm(LabeledComponentForm):
+class DeviceBulkAddComponentForm(ComponentForm):
     pk = forms.ModelMultipleChoiceField(
     pk = forms.ModelMultipleChoiceField(
         queryset=Device.objects.all(),
         queryset=Device.objects.all(),
         widget=forms.MultipleHiddenInput()
         widget=forms.MultipleHiddenInput()
@@ -3013,7 +3024,7 @@ class FrontPortForm(BootstrapMixin, forms.ModelForm):
     class Meta:
     class Meta:
         model = FrontPort
         model = FrontPort
         fields = [
         fields = [
-            'device', 'name', 'type', 'rear_port', 'rear_port_position', 'description', 'tags',
+            'device', 'name', 'label', 'type', 'rear_port', 'rear_port_position', 'description', 'tags',
         ]
         ]
         widgets = {
         widgets = {
             'device': forms.HiddenInput(),
             'device': forms.HiddenInput(),
@@ -3094,14 +3105,14 @@ class FrontPortCreateForm(ComponentCreateForm):
 
 
 
 
 # class FrontPortBulkCreateForm(
 # class FrontPortBulkCreateForm(
-#     form_from_model(FrontPort, ['type', 'description', 'tags']),
+#     form_from_model(FrontPort, ['label', 'type', 'description', 'tags']),
 #     DeviceBulkAddComponentForm
 #     DeviceBulkAddComponentForm
 # ):
 # ):
 #     pass
 #     pass
 
 
 
 
 class FrontPortBulkEditForm(
 class FrontPortBulkEditForm(
-    form_from_model(FrontPort, ['type', 'description']),
+    form_from_model(FrontPort, ['label', 'type', 'description']),
     BootstrapMixin,
     BootstrapMixin,
     AddRemoveTagsForm,
     AddRemoveTagsForm,
     BulkEditForm
     BulkEditForm
@@ -3112,9 +3123,7 @@ class FrontPortBulkEditForm(
     )
     )
 
 
     class Meta:
     class Meta:
-        nullable_fields = [
-            'description',
-        ]
+        nullable_fields = ('label', 'description')
 
 
 
 
 class FrontPortCSVForm(CSVModelForm):
 class FrontPortCSVForm(CSVModelForm):
@@ -3185,7 +3194,7 @@ class RearPortForm(BootstrapMixin, forms.ModelForm):
     class Meta:
     class Meta:
         model = RearPort
         model = RearPort
         fields = [
         fields = [
-            'device', 'name', 'type', 'positions', 'description', 'tags',
+            'device', 'name', 'label', 'type', 'positions', 'description', 'tags',
         ]
         ]
         widgets = {
         widgets = {
             'device': forms.HiddenInput(),
             'device': forms.HiddenInput(),
@@ -3210,14 +3219,14 @@ class RearPortCreateForm(ComponentCreateForm):
 
 
 
 
 class RearPortBulkCreateForm(
 class RearPortBulkCreateForm(
-    form_from_model(RearPort, ['type', 'positions', 'description', 'tags']),
+    form_from_model(RearPort, ['label', 'type', 'positions', 'description', 'tags']),
     DeviceBulkAddComponentForm
     DeviceBulkAddComponentForm
 ):
 ):
     pass
     pass
 
 
 
 
 class RearPortBulkEditForm(
 class RearPortBulkEditForm(
-    form_from_model(RearPort, ['type', 'description']),
+    form_from_model(RearPort, ['label', 'type', 'description']),
     BootstrapMixin,
     BootstrapMixin,
     AddRemoveTagsForm,
     AddRemoveTagsForm,
     BulkEditForm
     BulkEditForm
@@ -3228,9 +3237,7 @@ class RearPortBulkEditForm(
     )
     )
 
 
     class Meta:
     class Meta:
-        nullable_fields = [
-            'description',
-        ]
+        nullable_fields = ('label', 'description')
 
 
 
 
 class RearPortCSVForm(CSVModelForm):
 class RearPortCSVForm(CSVModelForm):
@@ -3392,17 +3399,11 @@ class InventoryItemForm(BootstrapMixin, forms.ModelForm):
     class Meta:
     class Meta:
         model = InventoryItem
         model = InventoryItem
         fields = [
         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(
     manufacturer = DynamicModelChoiceField(
         queryset=Manufacturer.objects.all(),
         queryset=Manufacturer.objects.all(),
         required=False
         required=False
@@ -3443,7 +3444,7 @@ class InventoryItemCSVForm(CSVModelForm):
 
 
 
 
 class InventoryItemBulkCreateForm(
 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
     DeviceBulkAddComponentForm
 ):
 ):
     tags = DynamicModelMultipleChoiceField(
     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(
     pk = forms.ModelMultipleChoiceField(
         queryset=InventoryItem.objects.all(),
         queryset=InventoryItem.objects.all(),
         widget=forms.MultipleHiddenInput()
         widget=forms.MultipleHiddenInput()
     )
     )
-    device = DynamicModelChoiceField(
-        queryset=Device.objects.all(),
-        required=False
-    )
     manufacturer = DynamicModelChoiceField(
     manufacturer = DynamicModelChoiceField(
         queryset=Manufacturer.objects.all(),
         queryset=Manufacturer.objects.all(),
         required=False
         required=False
     )
     )
-    part_id = forms.CharField(
-        max_length=50,
-        required=False,
-        label='Part ID'
-    )
-    description = forms.CharField(
-        max_length=100,
-        required=False
-    )
 
 
     class Meta:
     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
     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(
     manufacturer = DynamicModelMultipleChoiceField(
         queryset=Manufacturer.objects.all(),
         queryset=Manufacturer.objects.all(),
         to_field_name='slug',
         to_field_name='slug',
@@ -3522,6 +3482,12 @@ class InventoryItemFilterForm(BootstrapMixin, forms.Form):
             value_field="slug",
             value_field="slug",
         )
         )
     )
     )
+    serial = forms.CharField(
+        required=False
+    )
+    asset_tag = forms.CharField(
+        required=False
+    )
     discovered = forms.NullBooleanField(
     discovered = forms.NullBooleanField(
         required=False,
         required=False,
         widget=StaticSelect2(
         widget=StaticSelect2(

+ 33 - 10
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
 from django.db import migrations, models
 
 
 
 
@@ -11,32 +9,57 @@ class Migration(migrations.Migration):
 
 
     operations = [
     operations = [
         migrations.AddField(
         migrations.AddField(
-            model_name='interface',
+            model_name='consoleport',
             name='label',
             name='label',
             field=models.CharField(blank=True, max_length=64),
             field=models.CharField(blank=True, max_length=64),
         ),
         ),
         migrations.AddField(
         migrations.AddField(
-            model_name='interfacetemplate',
+            model_name='consoleporttemplate',
             name='label',
             name='label',
             field=models.CharField(blank=True, max_length=64),
             field=models.CharField(blank=True, max_length=64),
         ),
         ),
         migrations.AddField(
         migrations.AddField(
-            model_name='consoleport',
+            model_name='consoleserverport',
             name='label',
             name='label',
             field=models.CharField(blank=True, max_length=64),
             field=models.CharField(blank=True, max_length=64),
         ),
         ),
         migrations.AddField(
         migrations.AddField(
-            model_name='consoleporttemplate',
+            model_name='consoleserverporttemplate',
             name='label',
             name='label',
             field=models.CharField(blank=True, max_length=64),
             field=models.CharField(blank=True, max_length=64),
         ),
         ),
         migrations.AddField(
         migrations.AddField(
-            model_name='consoleserverport',
+            model_name='devicebay',
             name='label',
             name='label',
             field=models.CharField(blank=True, max_length=64),
             field=models.CharField(blank=True, max_length=64),
         ),
         ),
         migrations.AddField(
         migrations.AddField(
-            model_name='consoleserverporttemplate',
+            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',
             name='label',
             field=models.CharField(blank=True, max_length=64),
             field=models.CharField(blank=True, max_length=64),
         ),
         ),
@@ -61,12 +84,12 @@ class Migration(migrations.Migration):
             field=models.CharField(blank=True, max_length=64),
             field=models.CharField(blank=True, max_length=64),
         ),
         ),
         migrations.AddField(
         migrations.AddField(
-            model_name='devicebay',
+            model_name='rearport',
             name='label',
             name='label',
             field=models.CharField(blank=True, max_length=64),
             field=models.CharField(blank=True, max_length=64),
         ),
         ),
         migrations.AddField(
         migrations.AddField(
-            model_name='devicebaytemplate',
+            model_name='rearporttemplate',
             name='label',
             name='label',
             field=models.CharField(blank=True, max_length=64),
             field=models.CharField(blank=True, max_length=64),
         ),
         ),

+ 5 - 36
netbox/dcim/models/device_component_templates.py

@@ -27,6 +27,11 @@ __all__ = (
 
 
 
 
 class ComponentTemplateModel(models.Model):
 class ComponentTemplateModel(models.Model):
+    label = models.CharField(
+        max_length=64,
+        blank=True,
+        help_text="Physical label"
+    )
     description = models.CharField(
     description = models.CharField(
         max_length=200,
         max_length=200,
         blank=True
         blank=True
@@ -81,11 +86,6 @@ class ConsolePortTemplate(ComponentTemplateModel):
         max_length=100,
         max_length=100,
         blank=True
         blank=True
     )
     )
-    label = models.CharField(
-        max_length=64,
-        blank=True,
-        help_text="Physical label"
-    )
     type = models.CharField(
     type = models.CharField(
         max_length=50,
         max_length=50,
         choices=ConsolePortTypeChoices,
         choices=ConsolePortTypeChoices,
@@ -121,11 +121,6 @@ class ConsoleServerPortTemplate(ComponentTemplateModel):
         max_length=100,
         max_length=100,
         blank=True
         blank=True
     )
     )
-    label = models.CharField(
-        max_length=64,
-        blank=True,
-        help_text="Physical label"
-    )
     type = models.CharField(
     type = models.CharField(
         max_length=50,
         max_length=50,
         choices=ConsolePortTypeChoices,
         choices=ConsolePortTypeChoices,
@@ -161,11 +156,6 @@ class PowerPortTemplate(ComponentTemplateModel):
         max_length=100,
         max_length=100,
         blank=True
         blank=True
     )
     )
-    label = models.CharField(
-        max_length=64,
-        blank=True,
-        help_text="Physical label"
-    )
     type = models.CharField(
     type = models.CharField(
         max_length=50,
         max_length=50,
         choices=PowerPortTypeChoices,
         choices=PowerPortTypeChoices,
@@ -215,11 +205,6 @@ class PowerOutletTemplate(ComponentTemplateModel):
         max_length=100,
         max_length=100,
         blank=True
         blank=True
     )
     )
-    label = models.CharField(
-        max_length=64,
-        blank=True,
-        help_text="Physical label"
-    )
     type = models.CharField(
     type = models.CharField(
         max_length=50,
         max_length=50,
         choices=PowerOutletTypeChoices,
         choices=PowerOutletTypeChoices,
@@ -283,11 +268,6 @@ class InterfaceTemplate(ComponentTemplateModel):
         max_length=100,
         max_length=100,
         blank=True
         blank=True
     )
     )
-    label = models.CharField(
-        max_length=64,
-        blank=True,
-        help_text="Physical label"
-    )
     type = models.CharField(
     type = models.CharField(
         max_length=50,
         max_length=50,
         choices=InterfaceTypeChoices
         choices=InterfaceTypeChoices
@@ -348,9 +328,6 @@ class FrontPortTemplate(ComponentTemplateModel):
             ('rear_port', 'rear_port_position'),
             ('rear_port', 'rear_port_position'),
         )
         )
 
 
-    def __str__(self):
-        return self.name
-
     def clean(self):
     def clean(self):
 
 
         # Validate rear port assignment
         # Validate rear port assignment
@@ -411,9 +388,6 @@ class RearPortTemplate(ComponentTemplateModel):
         ordering = ('device_type', '_name')
         ordering = ('device_type', '_name')
         unique_together = ('device_type', 'name')
         unique_together = ('device_type', 'name')
 
 
-    def __str__(self):
-        return self.name
-
     def instantiate(self, device):
     def instantiate(self, device):
         return RearPort(
         return RearPort(
             device=device,
             device=device,
@@ -440,11 +414,6 @@ class DeviceBayTemplate(ComponentTemplateModel):
         max_length=100,
         max_length=100,
         blank=True
         blank=True
     )
     )
-    label = models.CharField(
-        max_length=64,
-        blank=True,
-        help_text="Physical label"
-    )
 
 
     class Meta:
     class Meta:
         ordering = ('device_type', '_name')
         ordering = ('device_type', '_name')

+ 23 - 53
netbox/dcim/models/device_components.py

@@ -36,6 +36,11 @@ __all__ = (
 
 
 
 
 class ComponentModel(models.Model):
 class ComponentModel(models.Model):
+    label = models.CharField(
+        max_length=64,
+        blank=True,
+        help_text="Physical label"
+    )
     description = models.CharField(
     description = models.CharField(
         max_length=200,
         max_length=200,
         blank=True
         blank=True
@@ -241,11 +246,6 @@ class ConsolePort(CableTermination, ComponentModel):
     name = models.CharField(
     name = models.CharField(
         max_length=50
         max_length=50
     )
     )
-    label = models.CharField(
-        max_length=64,
-        blank=True,
-        help_text="Physical label"
-    )
     _name = NaturalOrderingField(
     _name = NaturalOrderingField(
         target_field='name',
         target_field='name',
         max_length=100,
         max_length=100,
@@ -270,7 +270,7 @@ class ConsolePort(CableTermination, ComponentModel):
     )
     )
     tags = TaggableManager(through=TaggedItem)
     tags = TaggableManager(through=TaggedItem)
 
 
-    csv_headers = ['device', 'name', 'type', 'description']
+    csv_headers = ['device', 'name', 'label', 'type', 'description']
 
 
     class Meta:
     class Meta:
         ordering = ('device', '_name')
         ordering = ('device', '_name')
@@ -283,6 +283,7 @@ class ConsolePort(CableTermination, ComponentModel):
         return (
         return (
             self.device.identifier,
             self.device.identifier,
             self.name,
             self.name,
+            self.label,
             self.type,
             self.type,
             self.description,
             self.description,
         )
         )
@@ -310,11 +311,6 @@ class ConsoleServerPort(CableTermination, ComponentModel):
         max_length=100,
         max_length=100,
         blank=True
         blank=True
     )
     )
-    label = models.CharField(
-        max_length=64,
-        blank=True,
-        help_text="Physical label"
-    )
     type = models.CharField(
     type = models.CharField(
         max_length=50,
         max_length=50,
         choices=ConsolePortTypeChoices,
         choices=ConsolePortTypeChoices,
@@ -327,7 +323,7 @@ class ConsoleServerPort(CableTermination, ComponentModel):
     )
     )
     tags = TaggableManager(through=TaggedItem)
     tags = TaggableManager(through=TaggedItem)
 
 
-    csv_headers = ['device', 'name', 'type', 'description']
+    csv_headers = ['device', 'name', 'label', 'type', 'description']
 
 
     class Meta:
     class Meta:
         ordering = ('device', '_name')
         ordering = ('device', '_name')
@@ -340,6 +336,7 @@ class ConsoleServerPort(CableTermination, ComponentModel):
         return (
         return (
             self.device.identifier,
             self.device.identifier,
             self.name,
             self.name,
+            self.label,
             self.type,
             self.type,
             self.description,
             self.description,
         )
         )
@@ -367,11 +364,6 @@ class PowerPort(CableTermination, ComponentModel):
         max_length=100,
         max_length=100,
         blank=True
         blank=True
     )
     )
-    label = models.CharField(
-        max_length=64,
-        blank=True,
-        help_text="Physical label"
-    )
     type = models.CharField(
     type = models.CharField(
         max_length=50,
         max_length=50,
         choices=PowerPortTypeChoices,
         choices=PowerPortTypeChoices,
@@ -410,7 +402,7 @@ class PowerPort(CableTermination, ComponentModel):
     )
     )
     tags = TaggableManager(through=TaggedItem)
     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:
     class Meta:
         ordering = ('device', '_name')
         ordering = ('device', '_name')
@@ -423,6 +415,7 @@ class PowerPort(CableTermination, ComponentModel):
         return (
         return (
             self.device.identifier,
             self.device.identifier,
             self.name,
             self.name,
+            self.label,
             self.get_type_display(),
             self.get_type_display(),
             self.maximum_draw,
             self.maximum_draw,
             self.allocated_draw,
             self.allocated_draw,
@@ -532,11 +525,6 @@ class PowerOutlet(CableTermination, ComponentModel):
         max_length=100,
         max_length=100,
         blank=True
         blank=True
     )
     )
-    label = models.CharField(
-        max_length=64,
-        blank=True,
-        help_text="Physical label"
-    )
     type = models.CharField(
     type = models.CharField(
         max_length=50,
         max_length=50,
         choices=PowerOutletTypeChoices,
         choices=PowerOutletTypeChoices,
@@ -562,7 +550,7 @@ class PowerOutlet(CableTermination, ComponentModel):
     )
     )
     tags = TaggableManager(through=TaggedItem)
     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:
     class Meta:
         ordering = ('device', '_name')
         ordering = ('device', '_name')
@@ -575,6 +563,7 @@ class PowerOutlet(CableTermination, ComponentModel):
         return (
         return (
             self.device.identifier,
             self.device.identifier,
             self.name,
             self.name,
+            self.label,
             self.get_type_display(),
             self.get_type_display(),
             self.power_port.name if self.power_port else None,
             self.power_port.name if self.power_port else None,
             self.get_feed_leg_display(),
             self.get_feed_leg_display(),
@@ -640,11 +629,6 @@ class Interface(CableTermination, ComponentModel, BaseInterface):
         null=True,
         null=True,
         blank=True
         blank=True
     )
     )
-    label = models.CharField(
-        max_length=64,
-        blank=True,
-        help_text="Physical label"
-    )
     _connected_interface = models.OneToOneField(
     _connected_interface = models.OneToOneField(
         to='self',
         to='self',
         on_delete=models.SET_NULL,
         on_delete=models.SET_NULL,
@@ -703,7 +687,7 @@ class Interface(CableTermination, ComponentModel, BaseInterface):
     tags = TaggableManager(through=TaggedItem)
     tags = TaggableManager(through=TaggedItem)
 
 
     csv_headers = [
     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:
     class Meta:
@@ -717,6 +701,7 @@ class Interface(CableTermination, ComponentModel, BaseInterface):
         return (
         return (
             self.device.identifier if self.device else None,
             self.device.identifier if self.device else None,
             self.name,
             self.name,
+            self.label,
             self.lag.name if self.lag else None,
             self.lag.name if self.lag else None,
             self.get_type_display(),
             self.get_type_display(),
             self.enabled,
             self.enabled,
@@ -877,7 +862,7 @@ class FrontPort(CableTermination, ComponentModel):
     )
     )
     tags = TaggableManager(through=TaggedItem)
     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:
     class Meta:
         ordering = ('device', '_name')
         ordering = ('device', '_name')
@@ -886,9 +871,6 @@ class FrontPort(CableTermination, ComponentModel):
             ('rear_port', 'rear_port_position'),
             ('rear_port', 'rear_port_position'),
         )
         )
 
 
-    def __str__(self):
-        return self.name
-
     def get_absolute_url(self):
     def get_absolute_url(self):
         return reverse('dcim:frontport', kwargs={'pk': self.pk})
         return reverse('dcim:frontport', kwargs={'pk': self.pk})
 
 
@@ -896,6 +878,7 @@ class FrontPort(CableTermination, ComponentModel):
         return (
         return (
             self.device.identifier,
             self.device.identifier,
             self.name,
             self.name,
+            self.label,
             self.get_type_display(),
             self.get_type_display(),
             self.rear_port.name,
             self.rear_port.name,
             self.rear_port_position,
             self.rear_port_position,
@@ -947,15 +930,12 @@ class RearPort(CableTermination, ComponentModel):
     )
     )
     tags = TaggableManager(through=TaggedItem)
     tags = TaggableManager(through=TaggedItem)
 
 
-    csv_headers = ['device', 'name', 'type', 'positions', 'description']
+    csv_headers = ['device', 'name', 'label', 'type', 'positions', 'description']
 
 
     class Meta:
     class Meta:
         ordering = ('device', '_name')
         ordering = ('device', '_name')
         unique_together = ('device', 'name')
         unique_together = ('device', 'name')
 
 
-    def __str__(self):
-        return self.name
-
     def get_absolute_url(self):
     def get_absolute_url(self):
         return reverse('dcim:rearport', kwargs={'pk': self.pk})
         return reverse('dcim:rearport', kwargs={'pk': self.pk})
 
 
@@ -963,6 +943,7 @@ class RearPort(CableTermination, ComponentModel):
         return (
         return (
             self.device.identifier,
             self.device.identifier,
             self.name,
             self.name,
+            self.label,
             self.get_type_display(),
             self.get_type_display(),
             self.positions,
             self.positions,
             self.description,
             self.description,
@@ -992,11 +973,6 @@ class DeviceBay(ComponentModel):
         max_length=100,
         max_length=100,
         blank=True
         blank=True
     )
     )
-    label = models.CharField(
-        max_length=64,
-        blank=True,
-        help_text="Physical label"
-    )
     installed_device = models.OneToOneField(
     installed_device = models.OneToOneField(
         to='dcim.Device',
         to='dcim.Device',
         on_delete=models.SET_NULL,
         on_delete=models.SET_NULL,
@@ -1006,17 +982,12 @@ class DeviceBay(ComponentModel):
     )
     )
     tags = TaggableManager(through=TaggedItem)
     tags = TaggableManager(through=TaggedItem)
 
 
-    csv_headers = ['device', 'name', 'installed_device', 'description']
+    csv_headers = ['device', 'name', 'label', 'installed_device', 'description']
 
 
     class Meta:
     class Meta:
         ordering = ('device', '_name')
         ordering = ('device', '_name')
         unique_together = ('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):
     def get_absolute_url(self):
         return reverse('dcim:devicebay', kwargs={'pk': self.pk})
         return reverse('dcim:devicebay', kwargs={'pk': self.pk})
 
 
@@ -1024,6 +995,7 @@ class DeviceBay(ComponentModel):
         return (
         return (
             self.device.identifier,
             self.device.identifier,
             self.name,
             self.name,
+            self.label,
             self.installed_device.identifier if self.installed_device else None,
             self.installed_device.identifier if self.installed_device else None,
             self.description,
             self.description,
         )
         )
@@ -1116,16 +1088,13 @@ class InventoryItem(ComponentModel):
     tags = TaggableManager(through=TaggedItem)
     tags = TaggableManager(through=TaggedItem)
 
 
     csv_headers = [
     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:
     class Meta:
         ordering = ('device__id', 'parent__id', '_name')
         ordering = ('device__id', 'parent__id', '_name')
         unique_together = ('device', 'parent', 'name')
         unique_together = ('device', 'parent', 'name')
 
 
-    def __str__(self):
-        return self.name
-
     def get_absolute_url(self):
     def get_absolute_url(self):
         return reverse('dcim:inventoryitem', kwargs={'pk': self.pk})
         return reverse('dcim:inventoryitem', kwargs={'pk': self.pk})
 
 
@@ -1133,6 +1102,7 @@ class InventoryItem(ComponentModel):
         return (
         return (
             self.device.name or '{{{}}}'.format(self.device.pk),
             self.device.name or '{{{}}}'.format(self.device.pk),
             self.name,
             self.name,
+            self.label,
             self.manufacturer.name if self.manufacturer else None,
             self.manufacturer.name if self.manufacturer else None,
             self.part_id,
             self.part_id,
             self.serial,
             self.serial,

+ 3 - 2
netbox/dcim/tables.py

@@ -784,9 +784,10 @@ class InventoryItemTable(DeviceComponentTable):
     class Meta(DeviceComponentTable.Meta):
     class Meta(DeviceComponentTable.Meta):
         model = InventoryItem
         model = InventoryItem
         fields = (
         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')
 
 
 
 
 #
 #