From 538199a8b30b571c2d362c94d2dabe78f20ce309 Mon Sep 17 00:00:00 2001 From: pl0xym0r <148605740+pl0xym0r@users.noreply.github.com> Date: Thu, 21 Nov 2024 10:38:13 +0000 Subject: [PATCH 1/2] fixes 17465 add racktype on bulkimport and bulkedit of racks --- netbox/dcim/forms/bulk_edit.py | 7 ++++++- netbox/dcim/forms/bulk_import.py | 13 ++++++++++--- 2 files changed, 16 insertions(+), 4 deletions(-) diff --git a/netbox/dcim/forms/bulk_edit.py b/netbox/dcim/forms/bulk_edit.py index b2733b60ca0..e9a86cc4aa4 100644 --- a/netbox/dcim/forms/bulk_edit.py +++ b/netbox/dcim/forms/bulk_edit.py @@ -359,6 +359,11 @@ class RackBulkEditForm(NetBoxModelBulkEditForm): queryset=RackRole.objects.all(), required=False ) + rack_type = DynamicModelChoiceField( + label=_('Rack type'), + queryset=RackType.objects.all(), + required=False, + ) serial = forms.CharField( max_length=50, required=False, @@ -438,7 +443,7 @@ class RackBulkEditForm(NetBoxModelBulkEditForm): model = Rack fieldsets = ( - FieldSet('status', 'role', 'tenant', 'serial', 'asset_tag', 'description', name=_('Rack')), + FieldSet('status', 'role', 'tenant', 'serial', 'asset_tag', 'rack_type', 'description', name=_('Rack')), FieldSet('region', 'site_group', 'site', 'location', name=_('Location')), FieldSet( 'form_factor', 'width', 'u_height', 'desc_units', 'airflow', 'outer_width', 'outer_depth', 'outer_unit', diff --git a/netbox/dcim/forms/bulk_import.py b/netbox/dcim/forms/bulk_import.py index 58ae350913f..2444077024d 100644 --- a/netbox/dcim/forms/bulk_import.py +++ b/netbox/dcim/forms/bulk_import.py @@ -256,6 +256,13 @@ class RackImportForm(NetBoxModelImportForm): to_field_name='name', help_text=_('Name of assigned role') ) + rack_type = CSVModelChoiceField( + label=_('Rack type'), + queryset=RackType.objects.all(), + to_field_name='model', + required=False, + help_text=_('Rack type model') + ) form_factor = CSVChoiceField( label=_('Type'), choices=RackFormFactorChoices, @@ -289,9 +296,9 @@ class RackImportForm(NetBoxModelImportForm): class Meta: model = Rack fields = ( - 'site', 'location', 'name', 'facility_id', 'tenant', 'status', 'role', 'form_factor', 'serial', 'asset_tag', - 'width', 'u_height', 'desc_units', 'outer_width', 'outer_depth', 'outer_unit', 'mounting_depth', 'airflow', - 'weight', 'max_weight', 'weight_unit', 'description', 'comments', 'tags', + 'site', 'location', 'name', 'facility_id', 'tenant', 'status', 'role', 'rack_type', 'form_factor', 'serial', + 'asset_tag', 'width', 'u_height', 'desc_units', 'outer_width', 'outer_depth', 'outer_unit', 'mounting_depth', + 'airflow', 'weight', 'max_weight', 'weight_unit', 'description', 'comments', 'tags', ) def __init__(self, data=None, *args, **kwargs): From 6034b3df7b22eb687c1861e079a116997213a056 Mon Sep 17 00:00:00 2001 From: Jeremy Stretch Date: Wed, 11 Dec 2024 10:44:40 -0500 Subject: [PATCH 2/2] Make width & u_height optional when setting rack_type on import --- netbox/dcim/forms/bulk_import.py | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/netbox/dcim/forms/bulk_import.py b/netbox/dcim/forms/bulk_import.py index 2444077024d..76fae478b31 100644 --- a/netbox/dcim/forms/bulk_import.py +++ b/netbox/dcim/forms/bulk_import.py @@ -272,8 +272,13 @@ class RackImportForm(NetBoxModelImportForm): width = forms.ChoiceField( label=_('Width'), choices=RackWidthChoices, + required=False, help_text=_('Rail-to-rail width (in inches)') ) + u_height = forms.IntegerField( + required=False, + label=_('Height (U)') + ) outer_unit = CSVChoiceField( label=_('Outer unit'), choices=RackDimensionUnitChoices, @@ -297,8 +302,8 @@ class Meta: model = Rack fields = ( 'site', 'location', 'name', 'facility_id', 'tenant', 'status', 'role', 'rack_type', 'form_factor', 'serial', - 'asset_tag', 'width', 'u_height', 'desc_units', 'outer_width', 'outer_depth', 'outer_unit', 'mounting_depth', - 'airflow', 'weight', 'max_weight', 'weight_unit', 'description', 'comments', 'tags', + 'asset_tag', 'width', 'u_height', 'desc_units', 'outer_width', 'outer_depth', 'outer_unit', + 'mounting_depth', 'airflow', 'weight', 'max_weight', 'weight_unit', 'description', 'comments', 'tags', ) def __init__(self, data=None, *args, **kwargs): @@ -310,6 +315,16 @@ def __init__(self, data=None, *args, **kwargs): params = {f"site__{self.fields['site'].to_field_name}": data.get('site')} self.fields['location'].queryset = self.fields['location'].queryset.filter(**params) + def clean(self): + super().clean() + + # width & u_height must be set if not specifying a rack type on import + if not self.instance.pk: + if not self.cleaned_data.get('rack_type') and not self.cleaned_data.get('width'): + raise forms.ValidationError(_("Width must be set if not specifying a rack type.")) + if not self.cleaned_data.get('rack_type') and not self.cleaned_data.get('u_height'): + raise forms.ValidationError(_("U height must be set if not specifying a rack type.")) + class RackReservationImportForm(NetBoxModelImportForm): site = CSVModelChoiceField(