mirror of
https://github.com/netbox-community/netbox.git
synced 2025-07-14 01:41:22 -06:00
11969 airflow (#16967)
* 11960 Add airflow * 11960 Add airflow * 11960 fix tests * 11960 fix racktype form * 11969 different choices type * 11969 update docs * 11969 fix racktype copy * 11969 fix * Misc cleanup & reordering of form fields --------- Co-authored-by: Jeremy Stretch <jstretch@netboxlabs.com>
This commit is contained in:
parent
1d6987bca0
commit
e62a42286a
@ -39,3 +39,7 @@ An alternative part number to uniquely identify the module type.
|
|||||||
### Weight
|
### Weight
|
||||||
|
|
||||||
The numeric weight of the module, including a unit designation (e.g. 3 kilograms or 1 pound).
|
The numeric weight of the module, including a unit designation (e.g. 3 kilograms or 1 pound).
|
||||||
|
|
||||||
|
### Airflow
|
||||||
|
|
||||||
|
The direction in which air circulates through the device chassis for cooling.
|
||||||
|
@ -54,4 +54,7 @@ The maximum total weight capacity for all installed devices, inclusive of the ra
|
|||||||
|
|
||||||
If selected, the rack's elevation will display unit 1 at the top of the rack. (Most racks use ascending numbering, with unit 1 assigned to the bottommost position.)
|
If selected, the rack's elevation will display unit 1 at the top of the rack. (Most racks use ascending numbering, with unit 1 assigned to the bottommost position.)
|
||||||
|
|
||||||
|
### Airflow
|
||||||
|
|
||||||
|
The direction in which air circulates through the rack for cooling.
|
||||||
|
|
||||||
|
@ -62,13 +62,27 @@ class DeviceTypeSerializer(NetBoxModelSerializer):
|
|||||||
|
|
||||||
|
|
||||||
class ModuleTypeSerializer(NetBoxModelSerializer):
|
class ModuleTypeSerializer(NetBoxModelSerializer):
|
||||||
manufacturer = ManufacturerSerializer(nested=True)
|
manufacturer = ManufacturerSerializer(
|
||||||
weight_unit = ChoiceField(choices=WeightUnitChoices, allow_blank=True, required=False, allow_null=True)
|
nested=True
|
||||||
|
)
|
||||||
|
weight_unit = ChoiceField(
|
||||||
|
choices=WeightUnitChoices,
|
||||||
|
allow_blank=True,
|
||||||
|
required=False,
|
||||||
|
allow_null=True
|
||||||
|
)
|
||||||
|
airflow = ChoiceField(
|
||||||
|
choices=ModuleAirflowChoices,
|
||||||
|
allow_blank=True,
|
||||||
|
required=False,
|
||||||
|
allow_null=True
|
||||||
|
)
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
model = ModuleType
|
model = ModuleType
|
||||||
fields = [
|
fields = [
|
||||||
'id', 'url', 'display_url', 'display', 'manufacturer', 'model', 'part_number', 'weight', 'weight_unit',
|
'id', 'url', 'display_url', 'display', 'manufacturer', 'model', 'part_number', 'airflow',
|
||||||
'description', 'comments', 'tags', 'custom_fields', 'created', 'last_updated',
|
'weight', 'weight_unit', 'description', 'comments', 'tags', 'custom_fields',
|
||||||
|
'created', 'last_updated',
|
||||||
]
|
]
|
||||||
brief_fields = ('id', 'url', 'display', 'manufacturer', 'model', 'description')
|
brief_fields = ('id', 'url', 'display', 'manufacturer', 'model', 'description')
|
||||||
|
@ -64,14 +64,19 @@ class RackTypeSerializer(RackBaseSerializer):
|
|||||||
manufacturer = ManufacturerSerializer(
|
manufacturer = ManufacturerSerializer(
|
||||||
nested=True
|
nested=True
|
||||||
)
|
)
|
||||||
|
airflow = ChoiceField(
|
||||||
|
choices=RackAirflowChoices,
|
||||||
|
allow_blank=True,
|
||||||
|
required=False
|
||||||
|
)
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
model = RackType
|
model = RackType
|
||||||
fields = [
|
fields = [
|
||||||
'id', 'url', 'display_url', 'display', 'manufacturer', 'name', 'slug', 'description', 'form_factor',
|
'id', 'url', 'display_url', 'display', 'manufacturer', 'name', '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_depth', 'outer_unit', 'weight',
|
||||||
'max_weight', 'weight_unit', 'mounting_depth', 'description', 'comments', 'tags', 'custom_fields',
|
'max_weight', 'weight_unit', 'mounting_depth', 'airflow', 'description', 'comments', 'tags',
|
||||||
'created', 'last_updated',
|
'custom_fields', 'created', 'last_updated',
|
||||||
]
|
]
|
||||||
brief_fields = ('id', 'url', 'display', 'manufacturer', 'name', 'slug', 'description')
|
brief_fields = ('id', 'url', 'display', 'manufacturer', 'name', 'slug', 'description')
|
||||||
|
|
||||||
@ -95,6 +100,11 @@ class RackSerializer(RackBaseSerializer):
|
|||||||
choices=RackStatusChoices,
|
choices=RackStatusChoices,
|
||||||
required=False
|
required=False
|
||||||
)
|
)
|
||||||
|
airflow = ChoiceField(
|
||||||
|
choices=RackAirflowChoices,
|
||||||
|
allow_blank=True,
|
||||||
|
required=False
|
||||||
|
)
|
||||||
role = RackRoleSerializer(
|
role = RackRoleSerializer(
|
||||||
nested=True,
|
nested=True,
|
||||||
required=False,
|
required=False,
|
||||||
@ -124,7 +134,7 @@ class RackSerializer(RackBaseSerializer):
|
|||||||
'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_depth', 'outer_unit', 'mounting_depth',
|
||||||
'description', 'comments', 'tags', 'custom_fields', 'created', 'last_updated', 'device_count',
|
'airflow', 'description', 'comments', 'tags', 'custom_fields', 'created', 'last_updated', 'device_count',
|
||||||
'powerfeed_count',
|
'powerfeed_count',
|
||||||
]
|
]
|
||||||
brief_fields = ('id', 'url', 'display', 'name', 'description', 'device_count')
|
brief_fields = ('id', 'url', 'display', 'name', 'description', 'device_count')
|
||||||
|
@ -127,6 +127,17 @@ class RackElevationDetailRenderChoices(ChoiceSet):
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
class RackAirflowChoices(ChoiceSet):
|
||||||
|
|
||||||
|
AIRFLOW_FRONT_TO_REAR = 'front-to-rear'
|
||||||
|
AIRFLOW_REAR_TO_FRONT = 'rear-to-front'
|
||||||
|
|
||||||
|
CHOICES = (
|
||||||
|
(AIRFLOW_FRONT_TO_REAR, _('Front to rear')),
|
||||||
|
(AIRFLOW_REAR_TO_FRONT, _('Rear to front')),
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
#
|
#
|
||||||
# DeviceTypes
|
# DeviceTypes
|
||||||
#
|
#
|
||||||
@ -224,6 +235,25 @@ class ModuleStatusChoices(ChoiceSet):
|
|||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
|
class ModuleAirflowChoices(ChoiceSet):
|
||||||
|
|
||||||
|
AIRFLOW_FRONT_TO_REAR = 'front-to-rear'
|
||||||
|
AIRFLOW_REAR_TO_FRONT = 'rear-to-front'
|
||||||
|
AIRFLOW_LEFT_TO_RIGHT = 'left-to-right'
|
||||||
|
AIRFLOW_RIGHT_TO_LEFT = 'right-to-left'
|
||||||
|
AIRFLOW_SIDE_TO_REAR = 'side-to-rear'
|
||||||
|
AIRFLOW_PASSIVE = 'passive'
|
||||||
|
|
||||||
|
CHOICES = (
|
||||||
|
(AIRFLOW_FRONT_TO_REAR, _('Front to rear')),
|
||||||
|
(AIRFLOW_REAR_TO_FRONT, _('Rear to front')),
|
||||||
|
(AIRFLOW_LEFT_TO_RIGHT, _('Left to right')),
|
||||||
|
(AIRFLOW_RIGHT_TO_LEFT, _('Right to left')),
|
||||||
|
(AIRFLOW_SIDE_TO_REAR, _('Side to rear')),
|
||||||
|
(AIRFLOW_PASSIVE, _('Passive')),
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
#
|
#
|
||||||
# ConsolePorts
|
# ConsolePorts
|
||||||
#
|
#
|
||||||
|
@ -312,7 +312,7 @@ class RackTypeFilterSet(NetBoxModelFilterSet):
|
|||||||
model = RackType
|
model = RackType
|
||||||
fields = (
|
fields = (
|
||||||
'id', 'name', 'slug', 'u_height', 'starting_unit', 'desc_units', 'outer_width', 'outer_depth', 'outer_unit',
|
'id', 'name', 'slug', 'u_height', 'starting_unit', 'desc_units', 'outer_width', 'outer_depth', 'outer_unit',
|
||||||
'mounting_depth', 'weight', 'max_weight', 'weight_unit', 'description',
|
'mounting_depth', 'airflow', 'weight', 'max_weight', 'weight_unit', 'description',
|
||||||
)
|
)
|
||||||
|
|
||||||
def search(self, queryset, name, value):
|
def search(self, queryset, name, value):
|
||||||
@ -413,7 +413,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', 'weight', 'max_weight', 'weight_unit', 'description',
|
'outer_depth', 'outer_unit', 'mounting_depth', 'airflow', 'weight', 'max_weight', 'weight_unit',
|
||||||
|
'description',
|
||||||
)
|
)
|
||||||
|
|
||||||
def search(self, queryset, name, value):
|
def search(self, queryset, name, value):
|
||||||
@ -698,7 +699,7 @@ class ModuleTypeFilterSet(NetBoxModelFilterSet):
|
|||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
model = ModuleType
|
model = ModuleType
|
||||||
fields = ('id', 'model', 'part_number', 'weight', 'weight_unit', 'description')
|
fields = ('id', 'model', 'part_number', 'airflow', 'weight', 'weight_unit', 'description')
|
||||||
|
|
||||||
def search(self, queryset, name, value):
|
def search(self, queryset, name, value):
|
||||||
if not value.strip():
|
if not value.strip():
|
||||||
|
@ -268,6 +268,11 @@ class RackTypeBulkEditForm(NetBoxModelBulkEditForm):
|
|||||||
required=False,
|
required=False,
|
||||||
min_value=1
|
min_value=1
|
||||||
)
|
)
|
||||||
|
airflow = forms.ChoiceField(
|
||||||
|
label=_('Airflow'),
|
||||||
|
choices=add_blank_choice(RackAirflowChoices),
|
||||||
|
required=False
|
||||||
|
)
|
||||||
weight = forms.DecimalField(
|
weight = forms.DecimalField(
|
||||||
label=_('Weight'),
|
label=_('Weight'),
|
||||||
min_value=0,
|
min_value=0,
|
||||||
@ -293,10 +298,8 @@ class RackTypeBulkEditForm(NetBoxModelBulkEditForm):
|
|||||||
|
|
||||||
model = RackType
|
model = RackType
|
||||||
fieldsets = (
|
fieldsets = (
|
||||||
FieldSet('manufacturer', 'description', 'form_factor', name=_('Rack Type')),
|
FieldSet('manufacturer', 'description', 'form_factor', 'width', 'u_height', 'airflow', name=_('Rack Type')),
|
||||||
FieldSet(
|
FieldSet(
|
||||||
'width',
|
|
||||||
'u_height',
|
|
||||||
InlineFields('outer_width', 'outer_depth', 'outer_unit', label=_('Outer Dimensions')),
|
InlineFields('outer_width', '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',
|
||||||
@ -409,6 +412,11 @@ class RackBulkEditForm(NetBoxModelBulkEditForm):
|
|||||||
required=False,
|
required=False,
|
||||||
min_value=1
|
min_value=1
|
||||||
)
|
)
|
||||||
|
airflow = forms.ChoiceField(
|
||||||
|
label=_('Airflow'),
|
||||||
|
choices=add_blank_choice(RackAirflowChoices),
|
||||||
|
required=False
|
||||||
|
)
|
||||||
weight = forms.DecimalField(
|
weight = forms.DecimalField(
|
||||||
label=_('Weight'),
|
label=_('Weight'),
|
||||||
min_value=0,
|
min_value=0,
|
||||||
@ -437,7 +445,7 @@ class RackBulkEditForm(NetBoxModelBulkEditForm):
|
|||||||
FieldSet('status', 'role', 'tenant', 'serial', 'asset_tag', 'description', name=_('Rack')),
|
FieldSet('status', 'role', 'tenant', 'serial', 'asset_tag', 'description', name=_('Rack')),
|
||||||
FieldSet('region', 'site_group', 'site', 'location', name=_('Location')),
|
FieldSet('region', 'site_group', 'site', 'location', name=_('Location')),
|
||||||
FieldSet(
|
FieldSet(
|
||||||
'form_factor', 'width', 'u_height', 'desc_units', 'outer_width', 'outer_depth', 'outer_unit',
|
'form_factor', 'width', 'u_height', 'desc_units', 'airflow', 'outer_width', 'outer_depth', 'outer_unit',
|
||||||
'mounting_depth', name=_('Hardware')
|
'mounting_depth', name=_('Hardware')
|
||||||
),
|
),
|
||||||
FieldSet('weight', 'max_weight', 'weight_unit', name=_('Weight')),
|
FieldSet('weight', 'max_weight', 'weight_unit', name=_('Weight')),
|
||||||
@ -563,6 +571,11 @@ class ModuleTypeBulkEditForm(NetBoxModelBulkEditForm):
|
|||||||
label=_('Part number'),
|
label=_('Part number'),
|
||||||
required=False
|
required=False
|
||||||
)
|
)
|
||||||
|
airflow = forms.ChoiceField(
|
||||||
|
label=_('Airflow'),
|
||||||
|
choices=add_blank_choice(ModuleAirflowChoices),
|
||||||
|
required=False
|
||||||
|
)
|
||||||
weight = forms.DecimalField(
|
weight = forms.DecimalField(
|
||||||
label=_('Weight'),
|
label=_('Weight'),
|
||||||
min_value=0,
|
min_value=0,
|
||||||
@ -584,7 +597,11 @@ class ModuleTypeBulkEditForm(NetBoxModelBulkEditForm):
|
|||||||
model = ModuleType
|
model = ModuleType
|
||||||
fieldsets = (
|
fieldsets = (
|
||||||
FieldSet('manufacturer', 'part_number', 'description', name=_('Module Type')),
|
FieldSet('manufacturer', 'part_number', 'description', name=_('Module Type')),
|
||||||
FieldSet('weight', 'weight_unit', name=_('Weight')),
|
FieldSet(
|
||||||
|
'airflow',
|
||||||
|
InlineFields('weight', 'max_weight', 'weight_unit', label=_('Weight')),
|
||||||
|
name=_('Chassis')
|
||||||
|
),
|
||||||
)
|
)
|
||||||
nullable_fields = ('part_number', 'weight', 'weight_unit', 'description', 'comments')
|
nullable_fields = ('part_number', 'weight', 'weight_unit', 'description', 'comments')
|
||||||
|
|
||||||
|
@ -206,6 +206,12 @@ class RackTypeImportForm(NetBoxModelImportForm):
|
|||||||
required=False,
|
required=False,
|
||||||
help_text=_('Unit for outer dimensions')
|
help_text=_('Unit for outer dimensions')
|
||||||
)
|
)
|
||||||
|
airflow = CSVChoiceField(
|
||||||
|
label=_('Airflow'),
|
||||||
|
choices=RackAirflowChoices,
|
||||||
|
required=False,
|
||||||
|
help_text=_('Airflow direction')
|
||||||
|
)
|
||||||
weight_unit = CSVChoiceField(
|
weight_unit = CSVChoiceField(
|
||||||
label=_('Weight unit'),
|
label=_('Weight unit'),
|
||||||
choices=WeightUnitChoices,
|
choices=WeightUnitChoices,
|
||||||
@ -217,8 +223,8 @@ class RackTypeImportForm(NetBoxModelImportForm):
|
|||||||
model = RackType
|
model = RackType
|
||||||
fields = (
|
fields = (
|
||||||
'manufacturer', 'name', 'slug', 'form_factor', 'width', 'u_height', 'starting_unit', 'desc_units',
|
'manufacturer', 'name', '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_depth', 'outer_unit', 'mounting_depth', 'airflow', 'weight', 'max_weight',
|
||||||
'description', 'comments', 'tags',
|
'weight_unit', 'description', 'comments', 'tags',
|
||||||
)
|
)
|
||||||
|
|
||||||
def __init__(self, data=None, *args, **kwargs):
|
def __init__(self, data=None, *args, **kwargs):
|
||||||
@ -273,6 +279,12 @@ class RackImportForm(NetBoxModelImportForm):
|
|||||||
required=False,
|
required=False,
|
||||||
help_text=_('Unit for outer dimensions')
|
help_text=_('Unit for outer dimensions')
|
||||||
)
|
)
|
||||||
|
airflow = CSVChoiceField(
|
||||||
|
label=_('Airflow'),
|
||||||
|
choices=RackAirflowChoices,
|
||||||
|
required=False,
|
||||||
|
help_text=_('Airflow direction')
|
||||||
|
)
|
||||||
weight_unit = CSVChoiceField(
|
weight_unit = CSVChoiceField(
|
||||||
label=_('Weight unit'),
|
label=_('Weight unit'),
|
||||||
choices=WeightUnitChoices,
|
choices=WeightUnitChoices,
|
||||||
@ -284,8 +296,8 @@ class RackImportForm(NetBoxModelImportForm):
|
|||||||
model = Rack
|
model = Rack
|
||||||
fields = (
|
fields = (
|
||||||
'site', 'location', 'name', 'facility_id', 'tenant', 'status', 'role', 'form_factor', 'serial', 'asset_tag',
|
'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', 'weight',
|
'width', 'u_height', 'desc_units', 'outer_width', 'outer_depth', 'outer_unit', 'mounting_depth', 'airflow',
|
||||||
'max_weight', 'weight_unit', 'description', 'comments', 'tags',
|
'weight', 'max_weight', 'weight_unit', 'description', 'comments', 'tags',
|
||||||
)
|
)
|
||||||
|
|
||||||
def __init__(self, data=None, *args, **kwargs):
|
def __init__(self, data=None, *args, **kwargs):
|
||||||
@ -400,6 +412,12 @@ class ModuleTypeImportForm(NetBoxModelImportForm):
|
|||||||
queryset=Manufacturer.objects.all(),
|
queryset=Manufacturer.objects.all(),
|
||||||
to_field_name='name'
|
to_field_name='name'
|
||||||
)
|
)
|
||||||
|
airflow = CSVChoiceField(
|
||||||
|
label=_('Airflow'),
|
||||||
|
choices=ModuleAirflowChoices,
|
||||||
|
required=False,
|
||||||
|
help_text=_('Airflow direction')
|
||||||
|
)
|
||||||
weight = forms.DecimalField(
|
weight = forms.DecimalField(
|
||||||
label=_('Weight'),
|
label=_('Weight'),
|
||||||
required=False,
|
required=False,
|
||||||
@ -414,7 +432,7 @@ class ModuleTypeImportForm(NetBoxModelImportForm):
|
|||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
model = ModuleType
|
model = ModuleType
|
||||||
fields = ['manufacturer', 'model', 'part_number', 'description', 'weight', 'weight_unit', 'comments', 'tags']
|
fields = ['manufacturer', 'model', 'part_number', 'description', 'airflow', 'weight', 'weight_unit', 'comments', 'tags']
|
||||||
|
|
||||||
|
|
||||||
class DeviceRoleImportForm(NetBoxModelImportForm):
|
class DeviceRoleImportForm(NetBoxModelImportForm):
|
||||||
|
@ -267,6 +267,11 @@ class RackBaseFilterForm(NetBoxModelFilterSetForm):
|
|||||||
choices=BOOLEAN_WITH_BLANK_CHOICES
|
choices=BOOLEAN_WITH_BLANK_CHOICES
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
airflow = forms.MultipleChoiceField(
|
||||||
|
label=_('Airflow'),
|
||||||
|
choices=add_blank_choice(RackAirflowChoices),
|
||||||
|
required=False
|
||||||
|
)
|
||||||
weight = forms.DecimalField(
|
weight = forms.DecimalField(
|
||||||
label=_('Weight'),
|
label=_('Weight'),
|
||||||
required=False,
|
required=False,
|
||||||
@ -288,7 +293,7 @@ class RackTypeFilterForm(RackBaseFilterForm):
|
|||||||
model = RackType
|
model = RackType
|
||||||
fieldsets = (
|
fieldsets = (
|
||||||
FieldSet('q', 'filter_id', 'tag'),
|
FieldSet('q', 'filter_id', 'tag'),
|
||||||
FieldSet('form_factor', 'width', 'u_height', name=_('Rack Type')),
|
FieldSet('form_factor', 'width', 'u_height', 'airflow', name=_('Rack Type')),
|
||||||
FieldSet('starting_unit', 'desc_units', name=_('Numbering')),
|
FieldSet('starting_unit', 'desc_units', name=_('Numbering')),
|
||||||
FieldSet('weight', 'max_weight', 'weight_unit', name=_('Weight')),
|
FieldSet('weight', 'max_weight', 'weight_unit', name=_('Weight')),
|
||||||
)
|
)
|
||||||
@ -308,7 +313,7 @@ class RackFilterForm(TenancyFilterForm, ContactModelFilterForm, RackBaseFilterFo
|
|||||||
FieldSet('region_id', 'site_group_id', 'site_id', 'location_id', name=_('Location')),
|
FieldSet('region_id', 'site_group_id', 'site_id', 'location_id', name=_('Location')),
|
||||||
FieldSet('tenant_group_id', 'tenant_id', name=_('Tenant')),
|
FieldSet('tenant_group_id', 'tenant_id', name=_('Tenant')),
|
||||||
FieldSet('status', 'role_id', 'serial', 'asset_tag', name=_('Rack')),
|
FieldSet('status', 'role_id', 'serial', 'asset_tag', name=_('Rack')),
|
||||||
FieldSet('form_factor', 'width', 'u_height', name=_('Rack Type')),
|
FieldSet('form_factor', 'width', 'u_height', 'airflow', name=_('Rack Type')),
|
||||||
FieldSet('starting_unit', 'desc_units', name=_('Numbering')),
|
FieldSet('starting_unit', 'desc_units', name=_('Numbering')),
|
||||||
FieldSet('weight', 'max_weight', 'weight_unit', name=_('Weight')),
|
FieldSet('weight', 'max_weight', 'weight_unit', name=_('Weight')),
|
||||||
FieldSet('contact', 'contact_role', 'contact_group', name=_('Contacts')),
|
FieldSet('contact', 'contact_role', 'contact_group', name=_('Contacts')),
|
||||||
@ -578,7 +583,7 @@ class ModuleTypeFilterForm(NetBoxModelFilterSetForm):
|
|||||||
model = ModuleType
|
model = ModuleType
|
||||||
fieldsets = (
|
fieldsets = (
|
||||||
FieldSet('q', 'filter_id', 'tag'),
|
FieldSet('q', 'filter_id', 'tag'),
|
||||||
FieldSet('manufacturer_id', 'part_number', name=_('Hardware')),
|
FieldSet('manufacturer_id', 'part_number', 'airflow', name=_('Hardware')),
|
||||||
FieldSet(
|
FieldSet(
|
||||||
'console_ports', 'console_server_ports', 'power_ports', 'power_outlets', 'interfaces',
|
'console_ports', 'console_server_ports', 'power_ports', 'power_outlets', 'interfaces',
|
||||||
'pass_through_ports', name=_('Components')
|
'pass_through_ports', name=_('Components')
|
||||||
@ -638,6 +643,11 @@ class ModuleTypeFilterForm(NetBoxModelFilterSetForm):
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
tag = TagFilterField(model)
|
tag = TagFilterField(model)
|
||||||
|
airflow = forms.MultipleChoiceField(
|
||||||
|
label=_('Airflow'),
|
||||||
|
choices=add_blank_choice(ModuleAirflowChoices),
|
||||||
|
required=False
|
||||||
|
)
|
||||||
weight = forms.DecimalField(
|
weight = forms.DecimalField(
|
||||||
label=_('Weight'),
|
label=_('Weight'),
|
||||||
required=False
|
required=False
|
||||||
|
@ -211,7 +211,7 @@ class RackTypeForm(NetBoxModelForm):
|
|||||||
slug = SlugField()
|
slug = SlugField()
|
||||||
|
|
||||||
fieldsets = (
|
fieldsets = (
|
||||||
FieldSet('manufacturer', 'name', 'slug', 'description', 'form_factor', 'tags', name=_('Rack Type')),
|
FieldSet('manufacturer', 'name', 'slug', 'description', 'form_factor', 'airflow', '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_depth', 'outer_unit', label=_('Outer Dimensions')),
|
||||||
@ -226,7 +226,7 @@ class RackTypeForm(NetBoxModelForm):
|
|||||||
fields = [
|
fields = [
|
||||||
'manufacturer', 'name', 'slug', 'form_factor', 'width', 'u_height', 'starting_unit', 'desc_units',
|
'manufacturer', 'name', '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_depth', 'outer_unit', 'mounting_depth', 'weight', 'max_weight', 'weight_unit',
|
||||||
'description', 'comments', 'tags',
|
'airflow', 'description', 'comments', 'tags',
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
@ -268,8 +268,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', 'weight', 'max_weight', 'weight_unit', 'description',
|
'outer_depth', 'outer_unit', 'mounting_depth', 'airflow', 'weight', 'max_weight', 'weight_unit',
|
||||||
'comments', 'tags',
|
'description', 'comments', 'tags',
|
||||||
]
|
]
|
||||||
|
|
||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
@ -290,7 +290,7 @@ class RackForm(TenancyForm, NetBoxModelForm):
|
|||||||
self.fieldsets = (
|
self.fieldsets = (
|
||||||
*self.fieldsets,
|
*self.fieldsets,
|
||||||
FieldSet(
|
FieldSet(
|
||||||
'form_factor', 'width', 'starting_unit', 'u_height',
|
'form_factor', 'width', 'starting_unit', 'u_height', 'airflow',
|
||||||
InlineFields('outer_width', 'outer_depth', 'outer_unit', label=_('Outer Dimensions')),
|
InlineFields('outer_width', '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')
|
||||||
@ -398,13 +398,14 @@ class ModuleTypeForm(NetBoxModelForm):
|
|||||||
|
|
||||||
fieldsets = (
|
fieldsets = (
|
||||||
FieldSet('manufacturer', 'model', 'part_number', 'description', 'tags', name=_('Module Type')),
|
FieldSet('manufacturer', 'model', 'part_number', 'description', 'tags', name=_('Module Type')),
|
||||||
FieldSet('weight', 'weight_unit', name=_('Weight'))
|
FieldSet('airflow', 'weight', 'weight_unit', name=_('Chassis'))
|
||||||
)
|
)
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
model = ModuleType
|
model = ModuleType
|
||||||
fields = [
|
fields = [
|
||||||
'manufacturer', 'model', 'part_number', 'weight', 'weight_unit', 'description', 'comments', 'tags',
|
'manufacturer', 'model', 'part_number', 'airflow', 'weight', 'weight_unit', 'description',
|
||||||
|
'comments', 'tags',
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
|
@ -0,0 +1,28 @@
|
|||||||
|
# Generated by Django 5.0.7 on 2024-07-25 07:00
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('dcim', '0188_racktype'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='moduletype',
|
||||||
|
name='airflow',
|
||||||
|
field=models.CharField(blank=True, max_length=50),
|
||||||
|
),
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='rack',
|
||||||
|
name='airflow',
|
||||||
|
field=models.CharField(blank=True, max_length=50),
|
||||||
|
),
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='racktype',
|
||||||
|
name='airflow',
|
||||||
|
field=models.CharField(blank=True, max_length=50),
|
||||||
|
),
|
||||||
|
]
|
@ -388,8 +388,14 @@ class ModuleType(ImageAttachmentsMixin, PrimaryModel, WeightMixin):
|
|||||||
blank=True,
|
blank=True,
|
||||||
help_text=_('Discrete part number (optional)')
|
help_text=_('Discrete part number (optional)')
|
||||||
)
|
)
|
||||||
|
airflow = models.CharField(
|
||||||
|
verbose_name=_('airflow'),
|
||||||
|
max_length=50,
|
||||||
|
choices=ModuleAirflowChoices,
|
||||||
|
blank=True
|
||||||
|
)
|
||||||
|
|
||||||
clone_fields = ('manufacturer', 'weight', 'weight_unit',)
|
clone_fields = ('manufacturer', 'weight', 'weight_unit', 'airflow')
|
||||||
prerequisite_models = (
|
prerequisite_models = (
|
||||||
'dcim.Manufacturer',
|
'dcim.Manufacturer',
|
||||||
)
|
)
|
||||||
|
@ -53,6 +53,12 @@ class RackBase(WeightMixin, PrimaryModel):
|
|||||||
verbose_name=_('width'),
|
verbose_name=_('width'),
|
||||||
help_text=_('Rail-to-rail width')
|
help_text=_('Rail-to-rail width')
|
||||||
)
|
)
|
||||||
|
airflow = models.CharField(
|
||||||
|
verbose_name=_('airflow'),
|
||||||
|
max_length=50,
|
||||||
|
choices=RackAirflowChoices,
|
||||||
|
blank=True
|
||||||
|
)
|
||||||
|
|
||||||
# Numbering
|
# Numbering
|
||||||
u_height = models.PositiveSmallIntegerField(
|
u_height = models.PositiveSmallIntegerField(
|
||||||
@ -232,10 +238,10 @@ class Rack(ContactsMixin, ImageAttachmentsMixin, RackBase):
|
|||||||
Each Rack is assigned to a Site and (optionally) a Location.
|
Each Rack is assigned to a Site and (optionally) a Location.
|
||||||
"""
|
"""
|
||||||
# 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', 'outer_unit',
|
'form_factor', 'width', 'airflow', 'u_height', 'starting_unit', 'desc_units', 'outer_width', 'outer_depth',
|
||||||
'mounting_depth', 'weight', 'weight_unit', 'max_weight'
|
'outer_unit', 'mounting_depth', 'weight', 'weight_unit', 'max_weight',
|
||||||
]
|
)
|
||||||
|
|
||||||
rack_type = models.ForeignKey(
|
rack_type = models.ForeignKey(
|
||||||
to='dcim.RackType',
|
to='dcim.RackType',
|
||||||
@ -316,8 +322,8 @@ class Rack(ContactsMixin, ImageAttachmentsMixin, RackBase):
|
|||||||
)
|
)
|
||||||
|
|
||||||
clone_fields = (
|
clone_fields = (
|
||||||
'site', 'location', 'tenant', 'status', 'role', 'form_factor', 'width', 'u_height', 'desc_units', 'outer_width',
|
'site', 'location', 'tenant', 'status', 'role', 'form_factor', 'width', 'airflow', 'u_height', 'desc_units',
|
||||||
'outer_depth', 'outer_unit', 'mounting_depth', 'weight', 'max_weight', 'weight_unit',
|
'outer_width', 'outer_depth', 'outer_unit', 'mounting_depth', 'weight', 'max_weight', 'weight_unit',
|
||||||
)
|
)
|
||||||
prerequisite_models = (
|
prerequisite_models = (
|
||||||
'dcim.Site',
|
'dcim.Site',
|
||||||
|
@ -40,7 +40,7 @@ class ModuleTypeTable(NetBoxTable):
|
|||||||
class Meta(NetBoxTable.Meta):
|
class Meta(NetBoxTable.Meta):
|
||||||
model = ModuleType
|
model = ModuleType
|
||||||
fields = (
|
fields = (
|
||||||
'pk', 'id', 'model', 'manufacturer', 'part_number', 'weight', 'description', 'comments', 'tags',
|
'pk', 'id', 'model', 'manufacturer', 'part_number', 'airflow', 'weight', 'description', 'comments', 'tags',
|
||||||
)
|
)
|
||||||
default_columns = (
|
default_columns = (
|
||||||
'pk', 'model', 'manufacturer', 'part_number',
|
'pk', 'model', 'manufacturer', 'part_number',
|
||||||
|
@ -92,8 +92,8 @@ class RackTypeTable(NetBoxTable):
|
|||||||
model = RackType
|
model = RackType
|
||||||
fields = (
|
fields = (
|
||||||
'pk', 'id', 'name', 'manufacturer', 'form_factor', 'u_height', 'starting_unit', 'width', 'outer_width',
|
'pk', 'id', 'name', 'manufacturer', 'form_factor', 'u_height', 'starting_unit', 'width', 'outer_width',
|
||||||
'outer_depth', 'mounting_depth', 'weight', 'max_weight', 'description', 'comments', 'tags', 'created',
|
'outer_depth', 'mounting_depth', 'airflow', 'weight', 'max_weight', 'description', 'comments', 'tags',
|
||||||
'last_updated',
|
'created', 'last_updated',
|
||||||
)
|
)
|
||||||
default_columns = (
|
default_columns = (
|
||||||
'pk', 'name', 'manufacturer', 'type', 'u_height', 'description',
|
'pk', 'name', 'manufacturer', 'type', 'u_height', 'description',
|
||||||
@ -171,7 +171,7 @@ class RackTable(TenancyColumnsMixin, ContactsColumnMixin, NetBoxTable):
|
|||||||
fields = (
|
fields = (
|
||||||
'pk', 'id', 'name', 'site', 'location', 'status', 'facility_id', 'tenant', 'tenant_group', 'role', 'serial',
|
'pk', 'id', 'name', 'site', 'location', 'status', 'facility_id', 'tenant', 'tenant_group', 'role', 'serial',
|
||||||
'asset_tag', 'form_factor', 'u_height', 'starting_unit', 'width', 'outer_width', 'outer_depth',
|
'asset_tag', 'form_factor', 'u_height', 'starting_unit', 'width', 'outer_width', 'outer_depth',
|
||||||
'mounting_depth', 'weight', 'max_weight', 'comments', 'device_count', 'get_utilization',
|
'mounting_depth', 'airflow', 'weight', 'max_weight', 'comments', 'device_count', 'get_utilization',
|
||||||
'get_power_utilization', 'description', 'contacts', 'tags', 'created', 'last_updated',
|
'get_power_utilization', 'description', 'contacts', 'tags', 'created', 'last_updated',
|
||||||
)
|
)
|
||||||
default_columns = (
|
default_columns = (
|
||||||
|
@ -26,6 +26,12 @@
|
|||||||
<th scope="row">{% trans "Description" %}</th>
|
<th scope="row">{% trans "Description" %}</th>
|
||||||
<td>{{ object.description|placeholder }}</td>
|
<td>{{ object.description|placeholder }}</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<th scope="row">{% trans "Airflow" %}</th>
|
||||||
|
<td>
|
||||||
|
{{ object.get_airflow_display|placeholder }}
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<th scope="row">{% trans "Weight" %}</th>
|
<th scope="row">{% trans "Weight" %}</th>
|
||||||
<td>
|
<td>
|
||||||
|
@ -61,6 +61,10 @@
|
|||||||
<th scope="row">{% trans "Asset Tag" %}</th>
|
<th scope="row">{% trans "Asset Tag" %}</th>
|
||||||
<td class="font-monospace">{{ object.asset_tag|placeholder }}</td>
|
<td class="font-monospace">{{ object.asset_tag|placeholder }}</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<th scope="row">{% trans "Airflow" %}</th>
|
||||||
|
<td>{{ object.get_airflow_display|placeholder }}</td>
|
||||||
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<th scope="row">{% trans "Space Utilization" %}</th>
|
<th scope="row">{% trans "Space Utilization" %}</th>
|
||||||
<td>{% utilization_graph object.get_utilization %}</td>
|
<td>{% utilization_graph object.get_utilization %}</td>
|
||||||
|
@ -24,6 +24,10 @@
|
|||||||
<th scope="row">{% trans "Description" %}</th>
|
<th scope="row">{% trans "Description" %}</th>
|
||||||
<td>{{ object.description|placeholder }}</td>
|
<td>{{ object.description|placeholder }}</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<th scope="row">{% trans "Airflow" %}</th>
|
||||||
|
<td>{{ object.get_airflow_display|placeholder }}</td>
|
||||||
|
</tr>
|
||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
{% include 'dcim/inc/panels/racktype_dimensions.html' %}
|
{% include 'dcim/inc/panels/racktype_dimensions.html' %}
|
||||||
|
Loading…
Reference in New Issue
Block a user