Misc cleanup

This commit is contained in:
Jeremy Stretch 2024-07-14 15:27:15 -04:00
parent bb92c27231
commit b9b8652b95
15 changed files with 196 additions and 165 deletions

View File

@ -39,7 +39,6 @@ __all__ = [
'NestedRackReservationSerializer',
'NestedRackRoleSerializer',
'NestedRackSerializer',
'NestedRackTypeSerializer',
'NestedRearPortSerializer',
'NestedRearPortTemplateSerializer',
'NestedRegionSerializer',
@ -112,13 +111,6 @@ class NestedRackRoleSerializer(WritableNestedSerializer):
fields = ['id', 'url', 'display_url', 'display', 'name', 'slug', 'rack_count']
class NestedRackTypeSerializer(WritableNestedSerializer):
class Meta:
model = models.RackType
fields = ['id', 'url', 'display_url', 'display', 'name']
@extend_schema_serializer(
exclude_fields=('device_count',),
)

View File

@ -35,18 +35,36 @@ class RackRoleSerializer(NetBoxModelSerializer):
class RackTypeSerializer(NetBoxModelSerializer):
type = ChoiceField(choices=RackTypeChoices, allow_blank=True, required=False, allow_null=True)
width = ChoiceField(choices=RackWidthChoices, required=False)
outer_unit = ChoiceField(choices=RackDimensionUnitChoices, allow_blank=True, required=False, allow_null=True)
weight_unit = ChoiceField(choices=WeightUnitChoices, allow_blank=True, required=False, allow_null=True)
type = ChoiceField(
choices=RackTypeChoices,
allow_blank=True,
required=False,
allow_null=True
)
width = ChoiceField(
choices=RackWidthChoices,
required=False
)
outer_unit = ChoiceField(
choices=RackDimensionUnitChoices,
allow_blank=True,
required=False,
allow_null=True
)
weight_unit = ChoiceField(
choices=WeightUnitChoices,
allow_blank=True,
required=False,
allow_null=True
)
class Meta:
model = RackType
fields = [
'id', 'url', 'display_url', 'display', 'name', 'slug',
'type', 'width', 'u_height', 'starting_unit', 'weight', 'max_weight',
'weight_unit', 'desc_units', 'outer_width', 'outer_depth', 'outer_unit', 'mounting_depth', 'description',
'comments', 'tags', 'custom_fields', 'created', 'last_updated',
'id', 'url', 'display_url', 'display', 'name', 'slug', 'description', 'type', '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', 'created',
'last_updated',
]
brief_fields = ('id', 'url', 'display', 'name', 'slug', 'description')

View File

@ -12,10 +12,10 @@ router.register('sites', views.SiteViewSet)
# Racks
router.register('locations', views.LocationViewSet)
router.register('rack-types', views.RackTypeViewSet)
router.register('rack-roles', views.RackRoleViewSet)
router.register('racks', views.RackViewSet)
router.register('rack-reservations', views.RackReservationViewSet)
router.register('rack-types', views.RackTypeViewSet)
# Device/module types
router.register('manufacturers', views.ManufacturerViewSet)

View File

@ -13,7 +13,7 @@ from netbox.forms import NetBoxModelBulkEditForm
from tenancy.models import Tenant
from utilities.forms import BulkEditForm, add_blank_choice, form_from_model
from utilities.forms.fields import ColorField, CommentField, DynamicModelChoiceField, DynamicModelMultipleChoiceField
from utilities.forms.rendering import FieldSet
from utilities.forms.rendering import FieldSet, InlineFields
from utilities.forms.widgets import BulkEditNullBooleanSelect, NumberWithOptions
from wireless.models import WirelessLAN, WirelessLANGroup
from wireless.choices import WirelessRoleChoices
@ -234,6 +234,10 @@ class RackTypeBulkEditForm(NetBoxModelBulkEditForm):
required=False,
label=_('Height (U)')
)
starting_unit = forms.IntegerField(
required=False,
min_value=1
)
desc_units = forms.NullBooleanField(
required=False,
widget=BulkEditNullBooleanSelect,
@ -284,12 +288,14 @@ class RackTypeBulkEditForm(NetBoxModelBulkEditForm):
model = RackType
fieldsets = (
FieldSet('description', name=_('Rack')),
FieldSet('description', 'type', name=_('Rack Type')),
FieldSet(
'type', 'width', 'u_height', 'desc_units', 'outer_width', 'outer_depth', 'outer_unit', 'mounting_depth',
name=_('Hardware')
'width', 'u_height',
InlineFields('outer_width', 'outer_depth', 'outer_unit', label=_('Outer Dimensions')),
InlineFields('weight', 'max_weight', 'weight_unit', label=_('Weight')),
'mounting_depth', name=_('Dimensions')
),
FieldSet('weight', 'max_weight', 'weight_unit', name=_('Weight')),
FieldSet('starting_unit', 'desc_units', name=_('Numbering')),
)
nullable_fields = (
'outer_width', 'outer_depth', 'outer_unit', 'weight',

View File

@ -184,6 +184,11 @@ class RackTypeImportForm(NetBoxModelImportForm):
required=False,
help_text=_('Rack type')
)
starting_unit = forms.IntegerField(
required=False,
min_value=1,
help_text=_('The lowest-numbered position in the rack')
)
width = forms.ChoiceField(
label=_('Width'),
choices=RackWidthChoices,
@ -205,7 +210,7 @@ class RackTypeImportForm(NetBoxModelImportForm):
class Meta:
model = RackType
fields = (
'name', 'slug', 'type', 'width', 'u_height', 'desc_units', 'outer_width',
'name', 'slug', 'type', 'width', 'u_height', 'starting_unit', 'desc_units', 'outer_width',
'outer_depth', 'outer_unit', 'mounting_depth', 'weight',
'max_weight', 'weight_unit', 'description', 'comments', 'tags',
)

View File

@ -245,7 +245,7 @@ class RackTypeFilterForm(NetBoxModelFilterSetForm):
model = RackType
fieldsets = (
FieldSet('q', 'filter_id', 'tag'),
FieldSet('type', 'width', name=_('Hardware')),
FieldSet('type', 'width', 'u_height', 'starting_unit', name=_('Rack Type')),
FieldSet('weight', 'max_weight', 'weight_unit', name=_('Weight')),
)
selector_fields = ('filter_id', 'q',)
@ -259,7 +259,21 @@ class RackTypeFilterForm(NetBoxModelFilterSetForm):
choices=RackWidthChoices,
required=False
)
tag = TagFilterField(model)
u_height = forms.IntegerField(
required=False,
min_value=1
)
starting_unit = forms.IntegerField(
required=False,
min_value=1
)
desc_units = forms.NullBooleanField(
required=False,
label=_('Descending units'),
widget=forms.Select(
choices=BOOLEAN_WITH_BLANK_CHOICES
)
)
weight = forms.DecimalField(
label=_('Weight'),
required=False,
@ -275,6 +289,7 @@ class RackTypeFilterForm(NetBoxModelFilterSetForm):
choices=add_blank_choice(WeightUnitChoices),
required=False
)
tag = TagFilterField(model)
class RackFilterForm(TenancyFilterForm, ContactModelFilterForm, NetBoxModelFilterSetForm):

View File

@ -207,13 +207,14 @@ class RackTypeForm(NetBoxModelForm):
slug = SlugField()
fieldsets = (
FieldSet('name', 'slug', 'description', 'tags', name=_('Rack')),
FieldSet('name', 'slug', 'description', 'type', 'tags', name=_('Rack')),
FieldSet(
'type', 'width', 'starting_unit', 'u_height',
'width', 'u_height',
InlineFields('outer_width', 'outer_depth', 'outer_unit', label=_('Outer Dimensions')),
InlineFields('weight', 'max_weight', 'weight_unit', label=_('Weight')),
'mounting_depth', 'desc_units', name=_('Dimensions')
'mounting_depth', name=_('Dimensions')
),
FieldSet('starting_unit', 'desc_units', name=_('Numbering')),
)
class Meta:

View File

@ -37,7 +37,7 @@ __all__ = (
# Rack Types
#
class RackType(PrimaryModel, WeightMixin):
class RackType(WeightMixin, PrimaryModel):
"""
Devices are housed within Racks. Each rack has a defined height measured in rack units, and a front and rear face.
Each Rack is assigned to a Site and (optionally) a Location.
@ -124,10 +124,10 @@ class RackType(PrimaryModel, WeightMixin):
verbose_name=_('mounting depth'),
blank=True,
null=True,
help_text=(
_('Maximum depth of a mounted device, in millimeters. For four-post racks, this is the '
'distance between the front and rear rails.')
)
help_text=(_(
'Maximum depth of a mounted device, in millimeters. For four-post racks, this is the distance between the '
'front and rear rails.'
))
)
clone_fields = (

View File

@ -250,9 +250,7 @@ class RackTypeIndex(SearchIndex):
('description', 500),
('comments', 5000),
)
display_attrs = (
'site', 'description',
)
display_attrs = ('type', 'description')
@register_search

View File

@ -59,12 +59,6 @@ class RackTypeTable(NetBoxTable):
template_code="{{ value }}U",
verbose_name=_('Height')
)
comments = columns.MarkdownColumn(
verbose_name=_('Comments'),
)
tags = columns.TagColumn(
url_name='dcim:rack_list'
)
outer_width = tables.TemplateColumn(
template_code="{{ record.outer_width }} {{ record.outer_unit }}",
verbose_name=_('Outer Width')
@ -83,17 +77,21 @@ class RackTypeTable(NetBoxTable):
template_code=WEIGHT,
order_by=('_abs_max_weight', 'weight_unit')
)
comments = columns.MarkdownColumn(
verbose_name=_('Comments'),
)
tags = columns.TagColumn(
url_name='dcim:rack_list'
)
class Meta(NetBoxTable.Meta):
model = RackType
fields = (
'pk', 'id', 'name',
'type', 'u_height', 'starting_unit', 'width', 'outer_width', 'outer_depth', 'mounting_depth',
'weight', 'max_weight', 'comments',
'description', 'tags', 'created', 'last_updated',
'pk', 'id', 'name', 'type', 'u_height', 'starting_unit', 'width', 'outer_width', 'outer_depth',
'mounting_depth', 'weight', 'max_weight', 'description', 'comments', 'tags', 'created', 'last_updated',
)
default_columns = (
'pk', 'name', 'u_height',
'pk', 'name', 'type', 'u_height', 'description',
)

View File

@ -64,12 +64,12 @@ urlpatterns = [
path('racks/<int:pk>/', include(get_model_urls('dcim', 'rack'))),
# Rack Types
path('racktypes/', views.RackTypeListView.as_view(), name='racktype_list'),
path('racktypes/add/', views.RackTypeEditView.as_view(), name='racktype_add'),
path('racktypes/import/', views.RackTypeBulkImportView.as_view(), name='racktype_import'),
path('racktypes/edit/', views.RackTypeBulkEditView.as_view(), name='racktype_bulk_edit'),
path('racktypes/delete/', views.RackTypeBulkDeleteView.as_view(), name='racktype_bulk_delete'),
path('racktypes/<int:pk>/', include(get_model_urls('dcim', 'racktype'))),
path('rack-types/', views.RackTypeListView.as_view(), name='racktype_list'),
path('rack-types/add/', views.RackTypeEditView.as_view(), name='racktype_add'),
path('rack-types/import/', views.RackTypeBulkImportView.as_view(), name='racktype_import'),
path('rack-types/edit/', views.RackTypeBulkEditView.as_view(), name='racktype_bulk_edit'),
path('rack-types/delete/', views.RackTypeBulkDeleteView.as_view(), name='racktype_bulk_delete'),
path('rack-types/<int:pk>/', include(get_model_urls('dcim', 'racktype'))),
# Manufacturers
path('manufacturers/', views.ManufacturerListView.as_view(), name='manufacturer_list'),

View File

@ -588,13 +588,17 @@ class RackTypeListView(generic.ObjectListView):
filterset = filtersets.RackTypeFilterSet
filterset_form = forms.RackTypeFilterForm
table = tables.RackTypeTable
template_name = 'dcim/racktype_list.html'
@register_model_view(RackType)
class RackTypeView(GetRelatedModelsMixin, generic.ObjectView):
queryset = RackType.objects.all()
def get_extra_context(self, request, instance):
return {
'related_models': self.get_related_models(request, instance),
}
@register_model_view(RackType, 'edit')
class RackTypeEditView(generic.ObjectEditView):

View File

@ -24,6 +24,7 @@ ORGANIZATION_MENU = Menu(
label=_('Racks'),
items=(
get_model_item('dcim', 'rack', _('Racks')),
get_model_item('dcim', 'racktype', _('Rack Types')),
get_model_item('dcim', 'rackrole', _('Rack Roles')),
get_model_item('dcim', 'rackreservation', _('Reservations')),
MenuItem(
@ -33,12 +34,6 @@ ORGANIZATION_MENU = Menu(
),
),
),
MenuGroup(
label=_('Rack Types'),
items=(
get_model_item('dcim', 'racktype', _('Rack Types')),
),
),
MenuGroup(
label=_('Tenancy'),
items=(

View File

@ -1,4 +1,4 @@
{% extends 'dcim/rack/base.html' %}
{% extends 'generic/object.html' %}
{% load buttons %}
{% load helpers %}
{% load static %}
@ -8,108 +8,112 @@
{% block content %}
<div class="row">
<div class="col col-12 col-xl-5">
<div class="card">
<h5 class="card-header">{% trans "Rack Type" %}</h5>
<table class="table table-hover attr-table">
<tr>
<th scope="row">{% trans "Description" %}</th>
<td>{{ object.description|placeholder }}</td>
</tr>
</table>
</div>
<div class="card">
<h5 class="card-header">{% trans "Dimensions" %}</h5>
<table class="table table-hover attr-table">
<tr>
<th scope="row">{% trans "Type" %}</th>
<td>
{% if object.type %}
{{ object.get_type_display }}
{% else %}
{{ ''|placeholder }}
{% endif %}
</td>
</tr>
<tr>
<th scope="row">{% trans "Width" %}</th>
<td>{{ object.get_width_display }}</td>
</tr>
<tr>
<th scope="row">{% trans "Height" %}</th>
<td>{{ object.u_height }}U ({% if object.desc_units %}{% trans "descending" %}{% else %}{% trans "ascending" %}{% endif %})</td>
</tr>
<tr>
<th scope="row">{% trans "Starting Unit" %}</th>
<td>
{{ object.starting_unit }}
</td>
</tr>
<tr>
<th scope="row">{% trans "Outer Width" %}</th>
<td>
{% if object.outer_width %}
{{ object.outer_width }} {{ object.get_outer_unit_display }}
{% else %}
{{ ''|placeholder }}
{% endif %}
</td>
</tr>
<tr>
<th scope="row">{% trans "Outer Depth" %}</th>
<td>
{% if object.outer_depth %}
{{ object.outer_depth }} {{ object.get_outer_unit_display }}
{% else %}
{{ ''|placeholder }}
{% endif %}
</td>
</tr>
<tr>
<th scope="row">{% trans "Mounting Depth" %}</th>
<td>
{% if object.mounting_depth %}
{{ object.mounting_depth }} {% trans "Millimeters" %}
{% else %}
{{ ''|placeholder }}
{% endif %}
</td>
</tr>
<tr>
<th scope="row">{% trans "Rack Weight" %}</th>
<td>
{% if object.weight %}
{{ object.weight|floatformat }} {{ object.get_weight_unit_display }}
{% else %}
{{ ''|placeholder }}
{% endif %}
</td>
</tr>
<tr>
<th scope="row">{% trans "Maximum Weight" %}</th>
<td>
{% if object.max_weight %}
{{ object.max_weight }} {{ object.get_weight_unit_display }}
{% else %}
{{ ''|placeholder }}
{% endif %}
</td>
</tr>
</table>
</div>
{% include 'inc/panels/custom_fields.html' %}
{% include 'inc/panels/tags.html' %}
{% include 'inc/panels/comments.html' %}
{% plugin_left_page object %}
<div class="col col-6">
<div class="card">
<h5 class="card-header">{% trans "Rack Type" %}</h5>
<table class="table table-hover attr-table">
<tr>
<th scope="row">{% trans "Name" %}</th>
<td>{{ object.name }}</td>
</tr>
<tr>
<th scope="row">{% trans "Type" %}</th>
<td>
{% if object.type %}
{{ object.get_type_display }}
{% else %}
{{ ''|placeholder }}
{% endif %}
</td>
</tr>
<tr>
<th scope="row">{% trans "Description" %}</th>
<td>{{ object.description|placeholder }}</td>
</tr>
</table>
</div>
<div class="card">
<h5 class="card-header">{% trans "Dimensions" %}</h5>
<table class="table table-hover attr-table">
<tr>
<th scope="row">{% trans "Width" %}</th>
<td>{{ object.get_width_display }}</td>
</tr>
<tr>
<th scope="row">{% trans "Height" %}</th>
<td>{{ object.u_height }}U ({% if object.desc_units %}{% trans "descending" %}{% else %}{% trans "ascending" %}{% endif %})</td>
</tr>
<tr>
<th scope="row">{% trans "Starting Unit" %}</th>
<td>
{{ object.starting_unit }}
</td>
</tr>
<tr>
<th scope="row">{% trans "Outer Width" %}</th>
<td>
{% if object.outer_width %}
{{ object.outer_width }} {{ object.get_outer_unit_display }}
{% else %}
{{ ''|placeholder }}
{% endif %}
</td>
</tr>
<tr>
<th scope="row">{% trans "Outer Depth" %}</th>
<td>
{% if object.outer_depth %}
{{ object.outer_depth }} {{ object.get_outer_unit_display }}
{% else %}
{{ ''|placeholder }}
{% endif %}
</td>
</tr>
<tr>
<th scope="row">{% trans "Mounting Depth" %}</th>
<td>
{% if object.mounting_depth %}
{{ object.mounting_depth }} {% trans "Millimeters" %}
{% else %}
{{ ''|placeholder }}
{% endif %}
</td>
</tr>
<tr>
<th scope="row">{% trans "Rack Weight" %}</th>
<td>
{% if object.weight %}
{{ object.weight|floatformat }} {{ object.get_weight_unit_display }}
{% else %}
{{ ''|placeholder }}
{% endif %}
</td>
</tr>
<tr>
<th scope="row">{% trans "Maximum Weight" %}</th>
<td>
{% if object.max_weight %}
{{ object.max_weight }} {{ object.get_weight_unit_display }}
{% else %}
{{ ''|placeholder }}
{% endif %}
</td>
</tr>
</table>
</div>
{% include 'inc/panels/tags.html' %}
{% include 'inc/panels/comments.html' %}
{% plugin_left_page object %}
</div>
<div class="col col-12 col-xl-7">
{% include 'inc/panels/related_objects.html' %}
{% plugin_right_page object %}
<div class="col col-6">
{% include 'inc/panels/custom_fields.html' %}
{% include 'inc/panels/related_objects.html' %}
{% plugin_right_page object %}
</div>
</div>
<div class="row">
<div class="col col-md-12">
{% plugin_full_width_page object %}
</div>
<div class="col col-md-12">
{% plugin_full_width_page object %}
</div>
</div>
{% endblock %}

View File

@ -1,5 +0,0 @@
{% extends 'generic/object_list.html' %}
{% load helpers %}
{% load static %}
{% load i18n %}