mirror of
https://github.com/netbox-community/netbox.git
synced 2025-07-14 01:41:22 -06:00
18417 Add outer_height to racks (#18940)
* 18417 add rack outer height * 18417 add rack outer height * 18417 fix tests * 18417 fix validation message * Update netbox/dcim/filtersets.py Co-authored-by: Jeremy Stretch <jstretch@netboxlabs.com> * Update netbox/dcim/filtersets.py Co-authored-by: Jeremy Stretch <jstretch@netboxlabs.com> * Update netbox/dcim/models/racks.py Co-authored-by: Jeremy Stretch <jstretch@netboxlabs.com> * Update netbox/dcim/models/racks.py Co-authored-by: Jeremy Stretch <jstretch@netboxlabs.com> * Update netbox/dcim/models/racks.py Co-authored-by: Jeremy Stretch <jstretch@netboxlabs.com> * Update netbox/dcim/models/racks.py Co-authored-by: Jeremy Stretch <jstretch@netboxlabs.com> * 16224 review changes * 16224 review changes * 16224 update table display * 18417 use TemplateColumn * 18417 review changes --------- Co-authored-by: Jeremy Stretch <jstretch@netboxlabs.com>
This commit is contained in:
parent
fe7cc8cae9
commit
7a71c7b8f8
@ -40,7 +40,7 @@ The number of the numerically lowest unit in the rack. This value defaults to on
|
|||||||
|
|
||||||
### Outer Dimensions
|
### Outer Dimensions
|
||||||
|
|
||||||
The external width and depth of the rack can be tracked to aid in floorplan calculations. These measurements must be designated in either millimeters or inches.
|
The external width, height and depth of the rack can be tracked to aid in floorplan calculations. These measurements must be designated in either millimeters or inches.
|
||||||
|
|
||||||
### Mounting Depth
|
### Mounting Depth
|
||||||
|
|
||||||
|
@ -70,8 +70,8 @@ class RackTypeSerializer(RackBaseSerializer):
|
|||||||
model = RackType
|
model = RackType
|
||||||
fields = [
|
fields = [
|
||||||
'id', 'url', 'display_url', 'display', 'manufacturer', 'model', 'slug', 'description', 'form_factor',
|
'id', 'url', 'display_url', 'display', 'manufacturer', 'model', 'slug', 'description', 'form_factor',
|
||||||
'width', 'u_height', 'starting_unit', 'desc_units', 'outer_width', 'outer_depth', 'outer_unit', 'weight',
|
'width', 'u_height', 'starting_unit', 'desc_units', 'outer_width', 'outer_height', 'outer_depth',
|
||||||
'max_weight', 'weight_unit', 'mounting_depth', 'description', 'comments', 'tags',
|
'outer_unit', 'weight', 'max_weight', 'weight_unit', 'mounting_depth', 'description', 'comments', 'tags',
|
||||||
'custom_fields', 'created', 'last_updated',
|
'custom_fields', 'created', 'last_updated',
|
||||||
]
|
]
|
||||||
brief_fields = ('id', 'url', 'display', 'manufacturer', 'model', 'slug', 'description')
|
brief_fields = ('id', 'url', 'display', 'manufacturer', 'model', 'slug', 'description')
|
||||||
@ -129,9 +129,9 @@ class RackSerializer(RackBaseSerializer):
|
|||||||
fields = [
|
fields = [
|
||||||
'id', 'url', 'display_url', 'display', 'name', 'facility_id', 'site', 'location', 'tenant', 'status',
|
'id', 'url', 'display_url', 'display', 'name', 'facility_id', 'site', 'location', 'tenant', 'status',
|
||||||
'role', 'serial', 'asset_tag', 'rack_type', 'form_factor', 'width', 'u_height', 'starting_unit', 'weight',
|
'role', 'serial', 'asset_tag', 'rack_type', 'form_factor', 'width', 'u_height', 'starting_unit', 'weight',
|
||||||
'max_weight', 'weight_unit', 'desc_units', 'outer_width', 'outer_depth', 'outer_unit', 'mounting_depth',
|
'max_weight', 'weight_unit', 'desc_units', 'outer_width', 'outer_height', 'outer_depth', 'outer_unit',
|
||||||
'airflow', 'description', 'comments', 'tags', 'custom_fields', 'created', 'last_updated', 'device_count',
|
'mounting_depth', 'airflow', 'description', 'comments', 'tags', 'custom_fields',
|
||||||
'powerfeed_count',
|
'created', 'last_updated', 'device_count', 'powerfeed_count',
|
||||||
]
|
]
|
||||||
brief_fields = ('id', 'url', 'display', 'name', 'description', 'device_count')
|
brief_fields = ('id', 'url', 'display', 'name', 'description', 'device_count')
|
||||||
|
|
||||||
|
@ -313,8 +313,8 @@ class RackTypeFilterSet(NetBoxModelFilterSet):
|
|||||||
class Meta:
|
class Meta:
|
||||||
model = RackType
|
model = RackType
|
||||||
fields = (
|
fields = (
|
||||||
'id', 'model', 'slug', 'u_height', 'starting_unit', 'desc_units', 'outer_width', 'outer_depth',
|
'id', 'model', 'slug', 'u_height', 'starting_unit', 'desc_units', 'outer_width', 'outer_height',
|
||||||
'outer_unit', 'mounting_depth', 'weight', 'max_weight', 'weight_unit', 'description',
|
'outer_depth', 'outer_unit', 'mounting_depth', 'weight', 'max_weight', 'weight_unit', 'description',
|
||||||
)
|
)
|
||||||
|
|
||||||
def search(self, queryset, name, value):
|
def search(self, queryset, name, value):
|
||||||
@ -426,8 +426,8 @@ class RackFilterSet(NetBoxModelFilterSet, TenancyFilterSet, ContactModelFilterSe
|
|||||||
model = Rack
|
model = Rack
|
||||||
fields = (
|
fields = (
|
||||||
'id', 'name', 'facility_id', 'asset_tag', 'u_height', 'starting_unit', 'desc_units', 'outer_width',
|
'id', 'name', 'facility_id', 'asset_tag', 'u_height', 'starting_unit', 'desc_units', 'outer_width',
|
||||||
'outer_depth', 'outer_unit', 'mounting_depth', 'airflow', 'weight', 'max_weight', 'weight_unit',
|
'outer_height', 'outer_depth', 'outer_unit', 'mounting_depth', 'airflow', 'weight', 'max_weight',
|
||||||
'description',
|
'weight_unit', 'description',
|
||||||
)
|
)
|
||||||
|
|
||||||
def search(self, queryset, name, value):
|
def search(self, queryset, name, value):
|
||||||
|
@ -260,6 +260,11 @@ class RackTypeBulkEditForm(NetBoxModelBulkEditForm):
|
|||||||
required=False,
|
required=False,
|
||||||
min_value=1
|
min_value=1
|
||||||
)
|
)
|
||||||
|
outer_height = forms.IntegerField(
|
||||||
|
label=_('Outer height'),
|
||||||
|
required=False,
|
||||||
|
min_value=1
|
||||||
|
)
|
||||||
outer_depth = forms.IntegerField(
|
outer_depth = forms.IntegerField(
|
||||||
label=_('Outer depth'),
|
label=_('Outer depth'),
|
||||||
required=False,
|
required=False,
|
||||||
@ -302,7 +307,7 @@ class RackTypeBulkEditForm(NetBoxModelBulkEditForm):
|
|||||||
fieldsets = (
|
fieldsets = (
|
||||||
FieldSet('manufacturer', 'description', 'form_factor', 'width', 'u_height', name=_('Rack Type')),
|
FieldSet('manufacturer', 'description', 'form_factor', 'width', 'u_height', name=_('Rack Type')),
|
||||||
FieldSet(
|
FieldSet(
|
||||||
InlineFields('outer_width', 'outer_depth', 'outer_unit', label=_('Outer Dimensions')),
|
InlineFields('outer_width', 'outer_height', 'outer_depth', 'outer_unit', label=_('Outer Dimensions')),
|
||||||
InlineFields('weight', 'max_weight', 'weight_unit', label=_('Weight')),
|
InlineFields('weight', 'max_weight', 'weight_unit', label=_('Weight')),
|
||||||
'mounting_depth',
|
'mounting_depth',
|
||||||
name=_('Dimensions')
|
name=_('Dimensions')
|
||||||
@ -310,7 +315,7 @@ class RackTypeBulkEditForm(NetBoxModelBulkEditForm):
|
|||||||
FieldSet('starting_unit', 'desc_units', name=_('Numbering')),
|
FieldSet('starting_unit', 'desc_units', name=_('Numbering')),
|
||||||
)
|
)
|
||||||
nullable_fields = (
|
nullable_fields = (
|
||||||
'outer_width', 'outer_depth', 'outer_unit', 'weight',
|
'outer_width', 'outer_height', 'outer_depth', 'outer_unit', 'weight',
|
||||||
'max_weight', 'weight_unit', 'description', 'comments',
|
'max_weight', 'weight_unit', 'description', 'comments',
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -404,6 +409,11 @@ class RackBulkEditForm(NetBoxModelBulkEditForm):
|
|||||||
required=False,
|
required=False,
|
||||||
min_value=1
|
min_value=1
|
||||||
)
|
)
|
||||||
|
outer_height = forms.IntegerField(
|
||||||
|
label=_('Outer height'),
|
||||||
|
required=False,
|
||||||
|
min_value=1
|
||||||
|
)
|
||||||
outer_depth = forms.IntegerField(
|
outer_depth = forms.IntegerField(
|
||||||
label=_('Outer depth'),
|
label=_('Outer depth'),
|
||||||
required=False,
|
required=False,
|
||||||
@ -451,15 +461,13 @@ class RackBulkEditForm(NetBoxModelBulkEditForm):
|
|||||||
fieldsets = (
|
fieldsets = (
|
||||||
FieldSet('status', 'role', 'tenant', 'serial', 'asset_tag', 'rack_type', 'description', name=_('Rack')),
|
FieldSet('status', 'role', 'tenant', 'serial', 'asset_tag', 'rack_type', 'description', name=_('Rack')),
|
||||||
FieldSet('region', 'site_group', 'site', 'location', name=_('Location')),
|
FieldSet('region', 'site_group', 'site', 'location', name=_('Location')),
|
||||||
FieldSet(
|
FieldSet('outer_width', 'outer_height', 'outer_depth', 'outer_unit', name=_('Outer Dimensions')),
|
||||||
'form_factor', 'width', 'u_height', 'desc_units', 'airflow', 'outer_width', 'outer_depth', 'outer_unit',
|
FieldSet('form_factor', 'width', 'u_height', 'desc_units', 'airflow', 'mounting_depth', name=_('Hardware')),
|
||||||
'mounting_depth', name=_('Hardware')
|
|
||||||
),
|
|
||||||
FieldSet('weight', 'max_weight', 'weight_unit', name=_('Weight')),
|
FieldSet('weight', 'max_weight', 'weight_unit', name=_('Weight')),
|
||||||
)
|
)
|
||||||
nullable_fields = (
|
nullable_fields = (
|
||||||
'location', 'tenant', 'role', 'serial', 'asset_tag', 'outer_width', 'outer_depth', 'outer_unit', 'weight',
|
'location', 'tenant', 'role', 'serial', 'asset_tag', 'outer_width', 'outer_height', 'outer_depth',
|
||||||
'max_weight', 'weight_unit', 'description', 'comments',
|
'outer_unit', 'weight', 'max_weight', 'weight_unit', 'description', 'comments',
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@ -222,7 +222,7 @@ class RackTypeImportForm(NetBoxModelImportForm):
|
|||||||
model = RackType
|
model = RackType
|
||||||
fields = (
|
fields = (
|
||||||
'manufacturer', 'model', 'slug', 'form_factor', 'width', 'u_height', 'starting_unit', 'desc_units',
|
'manufacturer', 'model', 'slug', 'form_factor', 'width', 'u_height', 'starting_unit', 'desc_units',
|
||||||
'outer_width', 'outer_depth', 'outer_unit', 'mounting_depth', 'weight', 'max_weight',
|
'outer_width', 'outer_height', 'outer_depth', 'outer_unit', 'mounting_depth', 'weight', 'max_weight',
|
||||||
'weight_unit', 'description', 'comments', 'tags',
|
'weight_unit', 'description', 'comments', 'tags',
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -307,7 +307,7 @@ class RackImportForm(NetBoxModelImportForm):
|
|||||||
model = Rack
|
model = Rack
|
||||||
fields = (
|
fields = (
|
||||||
'site', 'location', 'name', 'facility_id', 'tenant', 'status', 'role', 'rack_type', 'form_factor', 'serial',
|
'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',
|
'asset_tag', 'width', 'u_height', 'desc_units', 'outer_width', 'outer_height', 'outer_depth', 'outer_unit',
|
||||||
'mounting_depth', 'airflow', 'weight', 'max_weight', 'weight_unit', 'description', 'comments', 'tags',
|
'mounting_depth', 'airflow', 'weight', 'max_weight', 'weight_unit', 'description', 'comments', 'tags',
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -226,7 +226,7 @@ class RackTypeForm(NetBoxModelForm):
|
|||||||
FieldSet('manufacturer', 'model', 'slug', 'description', 'form_factor', 'tags', name=_('Rack Type')),
|
FieldSet('manufacturer', 'model', 'slug', 'description', 'form_factor', 'tags', name=_('Rack Type')),
|
||||||
FieldSet(
|
FieldSet(
|
||||||
'width', 'u_height',
|
'width', 'u_height',
|
||||||
InlineFields('outer_width', 'outer_depth', 'outer_unit', label=_('Outer Dimensions')),
|
InlineFields('outer_width', 'outer_height', 'outer_depth', 'outer_unit', label=_('Outer Dimensions')),
|
||||||
InlineFields('weight', 'max_weight', 'weight_unit', label=_('Weight')),
|
InlineFields('weight', 'max_weight', 'weight_unit', label=_('Weight')),
|
||||||
'mounting_depth', name=_('Dimensions')
|
'mounting_depth', name=_('Dimensions')
|
||||||
),
|
),
|
||||||
@ -237,8 +237,8 @@ class RackTypeForm(NetBoxModelForm):
|
|||||||
model = RackType
|
model = RackType
|
||||||
fields = [
|
fields = [
|
||||||
'manufacturer', 'model', 'slug', 'form_factor', 'width', 'u_height', 'starting_unit', 'desc_units',
|
'manufacturer', 'model', 'slug', 'form_factor', 'width', 'u_height', 'starting_unit', 'desc_units',
|
||||||
'outer_width', 'outer_depth', 'outer_unit', 'mounting_depth', 'weight', 'max_weight', 'weight_unit',
|
'outer_width', 'outer_height', 'outer_depth', 'outer_unit', 'mounting_depth', 'weight', 'max_weight',
|
||||||
'description', 'comments', 'tags',
|
'weight_unit', 'description', 'comments', 'tags',
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
@ -283,8 +283,8 @@ class RackForm(TenancyForm, NetBoxModelForm):
|
|||||||
fields = [
|
fields = [
|
||||||
'site', 'location', 'name', 'facility_id', 'tenant_group', 'tenant', 'status', 'role', 'serial',
|
'site', 'location', 'name', 'facility_id', 'tenant_group', 'tenant', 'status', 'role', 'serial',
|
||||||
'asset_tag', 'rack_type', 'form_factor', 'width', 'u_height', 'starting_unit', 'desc_units', 'outer_width',
|
'asset_tag', 'rack_type', 'form_factor', 'width', 'u_height', 'starting_unit', 'desc_units', 'outer_width',
|
||||||
'outer_depth', 'outer_unit', 'mounting_depth', 'airflow', 'weight', 'max_weight', 'weight_unit',
|
'outer_height', 'outer_depth', 'outer_unit', 'mounting_depth', 'airflow', 'weight', 'max_weight',
|
||||||
'description', 'comments', 'tags',
|
'weight_unit', 'description', 'comments', 'tags',
|
||||||
]
|
]
|
||||||
|
|
||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
@ -306,7 +306,8 @@ class RackForm(TenancyForm, NetBoxModelForm):
|
|||||||
*self.fieldsets,
|
*self.fieldsets,
|
||||||
FieldSet(
|
FieldSet(
|
||||||
'form_factor', 'width', 'starting_unit', 'u_height',
|
'form_factor', 'width', 'starting_unit', 'u_height',
|
||||||
InlineFields('outer_width', 'outer_depth', 'outer_unit', label=_('Outer Dimensions')),
|
InlineFields('outer_width', 'outer_height', 'outer_depth', 'outer_unit',
|
||||||
|
label=_('Outer Dimensions')),
|
||||||
InlineFields('weight', 'max_weight', 'weight_unit', label=_('Weight')),
|
InlineFields('weight', 'max_weight', 'weight_unit', label=_('Weight')),
|
||||||
'mounting_depth', 'desc_units', name=_('Dimensions')
|
'mounting_depth', 'desc_units', name=_('Dimensions')
|
||||||
),
|
),
|
||||||
|
23
netbox/dcim/migrations/0203_add_rack_outer_height.py
Normal file
23
netbox/dcim/migrations/0203_add_rack_outer_height.py
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
# Generated by Django 5.2b1 on 2025-03-18 15:15
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('dcim', '0202_location_comments_region_comments_sitegroup_comments'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='rack',
|
||||||
|
name='outer_height',
|
||||||
|
field=models.PositiveSmallIntegerField(blank=True, null=True),
|
||||||
|
),
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='racktype',
|
||||||
|
name='outer_height',
|
||||||
|
field=models.PositiveSmallIntegerField(blank=True, null=True),
|
||||||
|
),
|
||||||
|
]
|
@ -73,6 +73,12 @@ class RackBase(WeightMixin, PrimaryModel):
|
|||||||
null=True,
|
null=True,
|
||||||
help_text=_('Outer dimension of rack (width)')
|
help_text=_('Outer dimension of rack (width)')
|
||||||
)
|
)
|
||||||
|
outer_height = models.PositiveSmallIntegerField(
|
||||||
|
verbose_name=_('outer height'),
|
||||||
|
blank=True,
|
||||||
|
null=True,
|
||||||
|
help_text=_('Outer dimension of rack (height)')
|
||||||
|
)
|
||||||
outer_depth = models.PositiveSmallIntegerField(
|
outer_depth = models.PositiveSmallIntegerField(
|
||||||
verbose_name=_('outer depth'),
|
verbose_name=_('outer depth'),
|
||||||
blank=True,
|
blank=True,
|
||||||
@ -140,7 +146,7 @@ class RackType(RackBase):
|
|||||||
)
|
)
|
||||||
|
|
||||||
clone_fields = (
|
clone_fields = (
|
||||||
'manufacturer', 'form_factor', 'width', 'u_height', 'desc_units', 'outer_width', 'outer_depth',
|
'manufacturer', 'form_factor', 'width', 'u_height', 'desc_units', 'outer_width', 'outer_height', 'outer_depth',
|
||||||
'outer_unit', 'mounting_depth', 'weight', 'max_weight', 'weight_unit',
|
'outer_unit', 'mounting_depth', 'weight', 'max_weight', 'weight_unit',
|
||||||
)
|
)
|
||||||
prerequisite_models = (
|
prerequisite_models = (
|
||||||
@ -173,8 +179,8 @@ class RackType(RackBase):
|
|||||||
super().clean()
|
super().clean()
|
||||||
|
|
||||||
# Validate outer dimensions and unit
|
# Validate outer dimensions and unit
|
||||||
if (self.outer_width is not None or self.outer_depth is not None) and not self.outer_unit:
|
if any([self.outer_width, self.outer_depth, self.outer_height]) and not self.outer_unit:
|
||||||
raise ValidationError(_("Must specify a unit when setting an outer width/depth"))
|
raise ValidationError(_("Must specify a unit when setting an outer dimension"))
|
||||||
|
|
||||||
# Validate max_weight and weight_unit
|
# Validate max_weight and weight_unit
|
||||||
if self.max_weight and not self.weight_unit:
|
if self.max_weight and not self.weight_unit:
|
||||||
@ -188,7 +194,7 @@ class RackType(RackBase):
|
|||||||
self._abs_max_weight = None
|
self._abs_max_weight = None
|
||||||
|
|
||||||
# Clear unit if outer width & depth are not set
|
# Clear unit if outer width & depth are not set
|
||||||
if self.outer_width is None and self.outer_depth is None:
|
if not any([self.outer_width, self.outer_depth, self.outer_height]):
|
||||||
self.outer_unit = None
|
self.outer_unit = None
|
||||||
|
|
||||||
super().save(*args, **kwargs)
|
super().save(*args, **kwargs)
|
||||||
@ -235,8 +241,8 @@ class Rack(ContactsMixin, ImageAttachmentsMixin, RackBase):
|
|||||||
"""
|
"""
|
||||||
# Fields which cannot be set locally if a RackType is assigned
|
# Fields which cannot be set locally if a RackType is assigned
|
||||||
RACKTYPE_FIELDS = (
|
RACKTYPE_FIELDS = (
|
||||||
'form_factor', 'width', 'u_height', 'starting_unit', 'desc_units', 'outer_width', 'outer_depth',
|
'form_factor', 'width', 'u_height', 'starting_unit', 'desc_units', 'outer_width', 'outer_height',
|
||||||
'outer_unit', 'mounting_depth', 'weight', 'weight_unit', 'max_weight',
|
'outer_depth', 'outer_unit', 'mounting_depth', 'weight', 'weight_unit', 'max_weight',
|
||||||
)
|
)
|
||||||
|
|
||||||
form_factor = models.CharField(
|
form_factor = models.CharField(
|
||||||
@ -329,7 +335,8 @@ class Rack(ContactsMixin, ImageAttachmentsMixin, RackBase):
|
|||||||
|
|
||||||
clone_fields = (
|
clone_fields = (
|
||||||
'site', 'location', 'tenant', 'status', 'role', 'form_factor', 'width', 'airflow', 'u_height', 'desc_units',
|
'site', 'location', 'tenant', 'status', 'role', 'form_factor', 'width', 'airflow', 'u_height', 'desc_units',
|
||||||
'outer_width', 'outer_depth', 'outer_unit', 'mounting_depth', 'weight', 'max_weight', 'weight_unit',
|
'outer_width', 'outer_height', 'outer_depth', 'outer_unit', 'mounting_depth', 'weight', 'max_weight',
|
||||||
|
'weight_unit',
|
||||||
)
|
)
|
||||||
prerequisite_models = (
|
prerequisite_models = (
|
||||||
'dcim.Site',
|
'dcim.Site',
|
||||||
@ -364,8 +371,8 @@ class Rack(ContactsMixin, ImageAttachmentsMixin, RackBase):
|
|||||||
raise ValidationError(_("Assigned location must belong to parent site ({site}).").format(site=self.site))
|
raise ValidationError(_("Assigned location must belong to parent site ({site}).").format(site=self.site))
|
||||||
|
|
||||||
# Validate outer dimensions and unit
|
# Validate outer dimensions and unit
|
||||||
if (self.outer_width is not None or self.outer_depth is not None) and not self.outer_unit:
|
if any([self.outer_width, self.outer_depth, self.outer_height]) and not self.outer_unit:
|
||||||
raise ValidationError(_("Must specify a unit when setting an outer width/depth"))
|
raise ValidationError(_("Must specify a unit when setting an outer dimension"))
|
||||||
|
|
||||||
# Validate max_weight and weight_unit
|
# Validate max_weight and weight_unit
|
||||||
if self.max_weight and not self.weight_unit:
|
if self.max_weight and not self.weight_unit:
|
||||||
@ -414,7 +421,7 @@ class Rack(ContactsMixin, ImageAttachmentsMixin, RackBase):
|
|||||||
self._abs_max_weight = None
|
self._abs_max_weight = None
|
||||||
|
|
||||||
# Clear unit if outer width & depth are not set
|
# Clear unit if outer width & depth are not set
|
||||||
if self.outer_width is None and self.outer_depth is None:
|
if not any([self.outer_width, self.outer_depth, self.outer_height]):
|
||||||
self.outer_unit = None
|
self.outer_unit = None
|
||||||
|
|
||||||
super().save(*args, **kwargs)
|
super().save(*args, **kwargs)
|
||||||
|
@ -5,7 +5,7 @@ from django_tables2.utils import Accessor
|
|||||||
from dcim.models import Rack, RackReservation, RackRole, RackType
|
from dcim.models import Rack, RackReservation, RackRole, RackType
|
||||||
from netbox.tables import NetBoxTable, columns
|
from netbox.tables import NetBoxTable, columns
|
||||||
from tenancy.tables import ContactsColumnMixin, TenancyColumnsMixin
|
from tenancy.tables import ContactsColumnMixin, TenancyColumnsMixin
|
||||||
from .template_code import WEIGHT
|
from .template_code import OUTER_UNIT, WEIGHT
|
||||||
|
|
||||||
__all__ = (
|
__all__ = (
|
||||||
'RackTable',
|
'RackTable',
|
||||||
@ -62,12 +62,16 @@ class RackTypeTable(NetBoxTable):
|
|||||||
template_code="{{ value }}U",
|
template_code="{{ value }}U",
|
||||||
verbose_name=_('Height')
|
verbose_name=_('Height')
|
||||||
)
|
)
|
||||||
outer_width = tables.TemplateColumn(
|
outer_width = columns.TemplateColumn(
|
||||||
template_code="{{ record.outer_width }} {{ record.outer_unit }}",
|
template_code=OUTER_UNIT,
|
||||||
verbose_name=_('Outer Width')
|
verbose_name=_('Outer Width')
|
||||||
)
|
)
|
||||||
outer_depth = tables.TemplateColumn(
|
outer_height = columns.TemplateColumn(
|
||||||
template_code="{{ record.outer_depth }} {{ record.outer_unit }}",
|
template_code=OUTER_UNIT,
|
||||||
|
verbose_name=_('Outer Height')
|
||||||
|
)
|
||||||
|
outer_depth = columns.TemplateColumn(
|
||||||
|
template_code=OUTER_UNIT,
|
||||||
verbose_name=_('Outer Depth')
|
verbose_name=_('Outer Depth')
|
||||||
)
|
)
|
||||||
weight = columns.TemplateColumn(
|
weight = columns.TemplateColumn(
|
||||||
@ -96,8 +100,8 @@ class RackTypeTable(NetBoxTable):
|
|||||||
model = RackType
|
model = RackType
|
||||||
fields = (
|
fields = (
|
||||||
'pk', 'id', 'model', 'manufacturer', 'form_factor', 'u_height', 'starting_unit', 'width', 'outer_width',
|
'pk', 'id', 'model', 'manufacturer', 'form_factor', 'u_height', 'starting_unit', 'width', 'outer_width',
|
||||||
'outer_depth', 'mounting_depth', 'airflow', 'weight', 'max_weight', 'description', 'comments',
|
'outer_height', 'outer_depth', 'mounting_depth', 'airflow', 'weight', 'max_weight', 'description',
|
||||||
'instance_count', 'tags', 'created', 'last_updated',
|
'comments', 'instance_count', 'tags', 'created', 'last_updated',
|
||||||
)
|
)
|
||||||
default_columns = (
|
default_columns = (
|
||||||
'pk', 'model', 'manufacturer', 'type', 'u_height', 'description', 'instance_count',
|
'pk', 'model', 'manufacturer', 'type', 'u_height', 'description', 'instance_count',
|
||||||
@ -159,12 +163,16 @@ class RackTable(TenancyColumnsMixin, ContactsColumnMixin, NetBoxTable):
|
|||||||
tags = columns.TagColumn(
|
tags = columns.TagColumn(
|
||||||
url_name='dcim:rack_list'
|
url_name='dcim:rack_list'
|
||||||
)
|
)
|
||||||
outer_width = tables.TemplateColumn(
|
outer_width = columns.TemplateColumn(
|
||||||
template_code="{{ record.outer_width }} {{ record.outer_unit }}",
|
template_code=OUTER_UNIT,
|
||||||
verbose_name=_('Outer Width')
|
verbose_name=_('Outer Width')
|
||||||
)
|
)
|
||||||
outer_depth = tables.TemplateColumn(
|
outer_height = columns.TemplateColumn(
|
||||||
template_code="{{ record.outer_depth }} {{ record.outer_unit }}",
|
template_code=OUTER_UNIT,
|
||||||
|
verbose_name=_('Outer Height')
|
||||||
|
)
|
||||||
|
outer_depth = columns.TemplateColumn(
|
||||||
|
template_code=OUTER_UNIT,
|
||||||
verbose_name=_('Outer Depth')
|
verbose_name=_('Outer Depth')
|
||||||
)
|
)
|
||||||
weight = columns.TemplateColumn(
|
weight = columns.TemplateColumn(
|
||||||
@ -183,8 +191,9 @@ class RackTable(TenancyColumnsMixin, ContactsColumnMixin, NetBoxTable):
|
|||||||
fields = (
|
fields = (
|
||||||
'pk', 'id', 'name', 'site', 'location', 'status', 'facility_id', 'tenant', 'tenant_group', 'role',
|
'pk', 'id', 'name', 'site', 'location', 'status', 'facility_id', 'tenant', 'tenant_group', 'role',
|
||||||
'rack_type', 'serial', 'asset_tag', 'form_factor', 'u_height', 'starting_unit', 'width', 'outer_width',
|
'rack_type', 'serial', 'asset_tag', 'form_factor', 'u_height', 'starting_unit', 'width', 'outer_width',
|
||||||
'outer_depth', 'mounting_depth', 'airflow', 'weight', 'max_weight', 'comments', 'device_count',
|
'outer_height', 'outer_depth', 'mounting_depth', 'airflow', 'weight', 'max_weight', 'comments',
|
||||||
'get_utilization', 'get_power_utilization', 'description', 'contacts', 'tags', 'created', 'last_updated',
|
'device_count', 'get_utilization', 'get_power_utilization', 'description', 'contacts',
|
||||||
|
'tags', 'created', 'last_updated',
|
||||||
)
|
)
|
||||||
default_columns = (
|
default_columns = (
|
||||||
'pk', 'name', 'site', 'location', 'status', 'facility_id', 'tenant', 'role', 'rack_type', 'u_height',
|
'pk', 'name', 'site', 'location', 'status', 'facility_id', 'tenant', 'role', 'rack_type', 'u_height',
|
||||||
|
@ -109,6 +109,11 @@ LOCATION_BUTTONS = """
|
|||||||
</a>
|
</a>
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
OUTER_UNIT = """
|
||||||
|
{% load helpers %}
|
||||||
|
{% if value %}{{ value }} {{ record.outer_unit }}{% endif %}
|
||||||
|
"""
|
||||||
|
|
||||||
#
|
#
|
||||||
# Device component templatebuttons
|
# Device component templatebuttons
|
||||||
#
|
#
|
||||||
|
@ -585,6 +585,7 @@ class RackTypeTestCase(TestCase, ChangeLoggedFilterSetTests):
|
|||||||
starting_unit=1,
|
starting_unit=1,
|
||||||
desc_units=False,
|
desc_units=False,
|
||||||
outer_width=100,
|
outer_width=100,
|
||||||
|
outer_height=100,
|
||||||
outer_depth=100,
|
outer_depth=100,
|
||||||
outer_unit=RackDimensionUnitChoices.UNIT_MILLIMETER,
|
outer_unit=RackDimensionUnitChoices.UNIT_MILLIMETER,
|
||||||
mounting_depth=100,
|
mounting_depth=100,
|
||||||
@ -603,6 +604,7 @@ class RackTypeTestCase(TestCase, ChangeLoggedFilterSetTests):
|
|||||||
starting_unit=2,
|
starting_unit=2,
|
||||||
desc_units=False,
|
desc_units=False,
|
||||||
outer_width=200,
|
outer_width=200,
|
||||||
|
outer_height=200,
|
||||||
outer_depth=200,
|
outer_depth=200,
|
||||||
outer_unit=RackDimensionUnitChoices.UNIT_MILLIMETER,
|
outer_unit=RackDimensionUnitChoices.UNIT_MILLIMETER,
|
||||||
mounting_depth=200,
|
mounting_depth=200,
|
||||||
@ -621,6 +623,7 @@ class RackTypeTestCase(TestCase, ChangeLoggedFilterSetTests):
|
|||||||
starting_unit=3,
|
starting_unit=3,
|
||||||
desc_units=True,
|
desc_units=True,
|
||||||
outer_width=300,
|
outer_width=300,
|
||||||
|
outer_height=300,
|
||||||
outer_depth=300,
|
outer_depth=300,
|
||||||
outer_unit=RackDimensionUnitChoices.UNIT_INCH,
|
outer_unit=RackDimensionUnitChoices.UNIT_INCH,
|
||||||
mounting_depth=300,
|
mounting_depth=300,
|
||||||
@ -681,6 +684,10 @@ class RackTypeTestCase(TestCase, ChangeLoggedFilterSetTests):
|
|||||||
params = {'outer_width': [100, 200]}
|
params = {'outer_width': [100, 200]}
|
||||||
self.assertEqual(self.filterset(params, self.queryset).qs.count(), 2)
|
self.assertEqual(self.filterset(params, self.queryset).qs.count(), 2)
|
||||||
|
|
||||||
|
def test_outer_height(self):
|
||||||
|
params = {'outer_height': [100, 200]}
|
||||||
|
self.assertEqual(self.filterset(params, self.queryset).qs.count(), 2)
|
||||||
|
|
||||||
def test_outer_depth(self):
|
def test_outer_depth(self):
|
||||||
params = {'outer_depth': [100, 200]}
|
params = {'outer_depth': [100, 200]}
|
||||||
self.assertEqual(self.filterset(params, self.queryset).qs.count(), 2)
|
self.assertEqual(self.filterset(params, self.queryset).qs.count(), 2)
|
||||||
@ -764,6 +771,7 @@ class RackTestCase(TestCase, ChangeLoggedFilterSetTests):
|
|||||||
starting_unit=1,
|
starting_unit=1,
|
||||||
desc_units=False,
|
desc_units=False,
|
||||||
outer_width=100,
|
outer_width=100,
|
||||||
|
outer_height=100,
|
||||||
outer_depth=100,
|
outer_depth=100,
|
||||||
outer_unit=RackDimensionUnitChoices.UNIT_MILLIMETER,
|
outer_unit=RackDimensionUnitChoices.UNIT_MILLIMETER,
|
||||||
mounting_depth=100,
|
mounting_depth=100,
|
||||||
@ -782,6 +790,7 @@ class RackTestCase(TestCase, ChangeLoggedFilterSetTests):
|
|||||||
starting_unit=2,
|
starting_unit=2,
|
||||||
desc_units=False,
|
desc_units=False,
|
||||||
outer_width=200,
|
outer_width=200,
|
||||||
|
outer_height=200,
|
||||||
outer_depth=200,
|
outer_depth=200,
|
||||||
outer_unit=RackDimensionUnitChoices.UNIT_MILLIMETER,
|
outer_unit=RackDimensionUnitChoices.UNIT_MILLIMETER,
|
||||||
mounting_depth=200,
|
mounting_depth=200,
|
||||||
@ -831,6 +840,7 @@ class RackTestCase(TestCase, ChangeLoggedFilterSetTests):
|
|||||||
u_height=42,
|
u_height=42,
|
||||||
desc_units=False,
|
desc_units=False,
|
||||||
outer_width=100,
|
outer_width=100,
|
||||||
|
outer_height=100,
|
||||||
outer_depth=100,
|
outer_depth=100,
|
||||||
outer_unit=RackDimensionUnitChoices.UNIT_MILLIMETER,
|
outer_unit=RackDimensionUnitChoices.UNIT_MILLIMETER,
|
||||||
weight=10,
|
weight=10,
|
||||||
@ -854,6 +864,7 @@ class RackTestCase(TestCase, ChangeLoggedFilterSetTests):
|
|||||||
u_height=43,
|
u_height=43,
|
||||||
desc_units=False,
|
desc_units=False,
|
||||||
outer_width=200,
|
outer_width=200,
|
||||||
|
outer_height=200,
|
||||||
outer_depth=200,
|
outer_depth=200,
|
||||||
outer_unit=RackDimensionUnitChoices.UNIT_MILLIMETER,
|
outer_unit=RackDimensionUnitChoices.UNIT_MILLIMETER,
|
||||||
weight=20,
|
weight=20,
|
||||||
@ -877,6 +888,7 @@ class RackTestCase(TestCase, ChangeLoggedFilterSetTests):
|
|||||||
u_height=44,
|
u_height=44,
|
||||||
desc_units=True,
|
desc_units=True,
|
||||||
outer_width=300,
|
outer_width=300,
|
||||||
|
outer_height=300,
|
||||||
outer_depth=300,
|
outer_depth=300,
|
||||||
outer_unit=RackDimensionUnitChoices.UNIT_INCH,
|
outer_unit=RackDimensionUnitChoices.UNIT_INCH,
|
||||||
weight=30,
|
weight=30,
|
||||||
@ -957,6 +969,10 @@ class RackTestCase(TestCase, ChangeLoggedFilterSetTests):
|
|||||||
params = {'outer_width': [100, 200]}
|
params = {'outer_width': [100, 200]}
|
||||||
self.assertEqual(self.filterset(params, self.queryset).qs.count(), 2)
|
self.assertEqual(self.filterset(params, self.queryset).qs.count(), 2)
|
||||||
|
|
||||||
|
def test_outer_height(self):
|
||||||
|
params = {'outer_height': [100, 200]}
|
||||||
|
self.assertEqual(self.filterset(params, self.queryset).qs.count(), 2)
|
||||||
|
|
||||||
def test_outer_depth(self):
|
def test_outer_depth(self):
|
||||||
params = {'outer_depth': [100, 200]}
|
params = {'outer_depth': [100, 200]}
|
||||||
self.assertEqual(self.filterset(params, self.queryset).qs.count(), 2)
|
self.assertEqual(self.filterset(params, self.queryset).qs.count(), 2)
|
||||||
|
@ -24,6 +24,16 @@
|
|||||||
{% endif %}
|
{% endif %}
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<th scope="row">{% trans "Outer Height" %}</th>
|
||||||
|
<td>
|
||||||
|
{% if object.outer_height %}
|
||||||
|
{{ object.outer_height }} {{ object.get_outer_unit_display }}
|
||||||
|
{% else %}
|
||||||
|
{{ ''|placeholder }}
|
||||||
|
{% endif %}
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<th scope="row">{% trans "Outer Depth" %}</th>
|
<th scope="row">{% trans "Outer Depth" %}</th>
|
||||||
<td>
|
<td>
|
||||||
|
Loading…
Reference in New Issue
Block a user