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', 'NestedRackReservationSerializer',
'NestedRackRoleSerializer', 'NestedRackRoleSerializer',
'NestedRackSerializer', 'NestedRackSerializer',
'NestedRackTypeSerializer',
'NestedRearPortSerializer', 'NestedRearPortSerializer',
'NestedRearPortTemplateSerializer', 'NestedRearPortTemplateSerializer',
'NestedRegionSerializer', 'NestedRegionSerializer',
@ -112,13 +111,6 @@ class NestedRackRoleSerializer(WritableNestedSerializer):
fields = ['id', 'url', 'display_url', 'display', 'name', 'slug', 'rack_count'] 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( @extend_schema_serializer(
exclude_fields=('device_count',), exclude_fields=('device_count',),
) )

View File

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

View File

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

View File

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

View File

@ -184,6 +184,11 @@ class RackTypeImportForm(NetBoxModelImportForm):
required=False, required=False,
help_text=_('Rack type') 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( width = forms.ChoiceField(
label=_('Width'), label=_('Width'),
choices=RackWidthChoices, choices=RackWidthChoices,
@ -205,7 +210,7 @@ class RackTypeImportForm(NetBoxModelImportForm):
class Meta: class Meta:
model = RackType model = RackType
fields = ( 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', 'outer_depth', 'outer_unit', 'mounting_depth', 'weight',
'max_weight', 'weight_unit', 'description', 'comments', 'tags', 'max_weight', 'weight_unit', 'description', 'comments', 'tags',
) )

View File

@ -245,7 +245,7 @@ class RackTypeFilterForm(NetBoxModelFilterSetForm):
model = RackType model = RackType
fieldsets = ( fieldsets = (
FieldSet('q', 'filter_id', 'tag'), 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')), FieldSet('weight', 'max_weight', 'weight_unit', name=_('Weight')),
) )
selector_fields = ('filter_id', 'q',) selector_fields = ('filter_id', 'q',)
@ -259,7 +259,21 @@ class RackTypeFilterForm(NetBoxModelFilterSetForm):
choices=RackWidthChoices, choices=RackWidthChoices,
required=False 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( weight = forms.DecimalField(
label=_('Weight'), label=_('Weight'),
required=False, required=False,
@ -275,6 +289,7 @@ class RackTypeFilterForm(NetBoxModelFilterSetForm):
choices=add_blank_choice(WeightUnitChoices), choices=add_blank_choice(WeightUnitChoices),
required=False required=False
) )
tag = TagFilterField(model)
class RackFilterForm(TenancyFilterForm, ContactModelFilterForm, NetBoxModelFilterSetForm): class RackFilterForm(TenancyFilterForm, ContactModelFilterForm, NetBoxModelFilterSetForm):

View File

@ -207,13 +207,14 @@ class RackTypeForm(NetBoxModelForm):
slug = SlugField() slug = SlugField()
fieldsets = ( fieldsets = (
FieldSet('name', 'slug', 'description', 'tags', name=_('Rack')), FieldSet('name', 'slug', 'description', 'type', 'tags', name=_('Rack')),
FieldSet( FieldSet(
'type', 'width', 'starting_unit', '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')),
InlineFields('weight', 'max_weight', 'weight_unit', label=_('Weight')), 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: class Meta:

View File

@ -37,7 +37,7 @@ __all__ = (
# Rack Types # 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. 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. Each Rack is assigned to a Site and (optionally) a Location.
@ -124,10 +124,10 @@ class RackType(PrimaryModel, WeightMixin):
verbose_name=_('mounting depth'), verbose_name=_('mounting depth'),
blank=True, blank=True,
null=True, null=True,
help_text=( help_text=(_(
_('Maximum depth of a mounted device, in millimeters. For four-post racks, this is the ' 'Maximum depth of a mounted device, in millimeters. For four-post racks, this is the distance between the '
'distance between the front and rear rails.') 'front and rear rails.'
) ))
) )
clone_fields = ( clone_fields = (

View File

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

View File

@ -59,12 +59,6 @@ class RackTypeTable(NetBoxTable):
template_code="{{ value }}U", template_code="{{ value }}U",
verbose_name=_('Height') verbose_name=_('Height')
) )
comments = columns.MarkdownColumn(
verbose_name=_('Comments'),
)
tags = columns.TagColumn(
url_name='dcim:rack_list'
)
outer_width = tables.TemplateColumn( outer_width = tables.TemplateColumn(
template_code="{{ record.outer_width }} {{ record.outer_unit }}", template_code="{{ record.outer_width }} {{ record.outer_unit }}",
verbose_name=_('Outer Width') verbose_name=_('Outer Width')
@ -83,17 +77,21 @@ class RackTypeTable(NetBoxTable):
template_code=WEIGHT, template_code=WEIGHT,
order_by=('_abs_max_weight', 'weight_unit') 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): class Meta(NetBoxTable.Meta):
model = RackType model = RackType
fields = ( fields = (
'pk', 'id', 'name', 'pk', 'id', 'name', 'type', 'u_height', 'starting_unit', 'width', 'outer_width', 'outer_depth',
'type', 'u_height', 'starting_unit', 'width', 'outer_width', 'outer_depth', 'mounting_depth', 'mounting_depth', 'weight', 'max_weight', 'description', 'comments', 'tags', 'created', 'last_updated',
'weight', 'max_weight', 'comments',
'description', 'tags', 'created', 'last_updated',
) )
default_columns = ( 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'))), path('racks/<int:pk>/', include(get_model_urls('dcim', 'rack'))),
# Rack Types # Rack Types
path('racktypes/', views.RackTypeListView.as_view(), name='racktype_list'), path('rack-types/', views.RackTypeListView.as_view(), name='racktype_list'),
path('racktypes/add/', views.RackTypeEditView.as_view(), name='racktype_add'), path('rack-types/add/', views.RackTypeEditView.as_view(), name='racktype_add'),
path('racktypes/import/', views.RackTypeBulkImportView.as_view(), name='racktype_import'), path('rack-types/import/', views.RackTypeBulkImportView.as_view(), name='racktype_import'),
path('racktypes/edit/', views.RackTypeBulkEditView.as_view(), name='racktype_bulk_edit'), path('rack-types/edit/', views.RackTypeBulkEditView.as_view(), name='racktype_bulk_edit'),
path('racktypes/delete/', views.RackTypeBulkDeleteView.as_view(), name='racktype_bulk_delete'), path('rack-types/delete/', views.RackTypeBulkDeleteView.as_view(), name='racktype_bulk_delete'),
path('racktypes/<int:pk>/', include(get_model_urls('dcim', 'racktype'))), path('rack-types/<int:pk>/', include(get_model_urls('dcim', 'racktype'))),
# Manufacturers # Manufacturers
path('manufacturers/', views.ManufacturerListView.as_view(), name='manufacturer_list'), path('manufacturers/', views.ManufacturerListView.as_view(), name='manufacturer_list'),

View File

@ -588,13 +588,17 @@ class RackTypeListView(generic.ObjectListView):
filterset = filtersets.RackTypeFilterSet filterset = filtersets.RackTypeFilterSet
filterset_form = forms.RackTypeFilterForm filterset_form = forms.RackTypeFilterForm
table = tables.RackTypeTable table = tables.RackTypeTable
template_name = 'dcim/racktype_list.html'
@register_model_view(RackType) @register_model_view(RackType)
class RackTypeView(GetRelatedModelsMixin, generic.ObjectView): class RackTypeView(GetRelatedModelsMixin, generic.ObjectView):
queryset = RackType.objects.all() 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') @register_model_view(RackType, 'edit')
class RackTypeEditView(generic.ObjectEditView): class RackTypeEditView(generic.ObjectEditView):

View File

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

View File

@ -1,4 +1,4 @@
{% extends 'dcim/rack/base.html' %} {% extends 'generic/object.html' %}
{% load buttons %} {% load buttons %}
{% load helpers %} {% load helpers %}
{% load static %} {% load static %}
@ -8,19 +8,14 @@
{% block content %} {% block content %}
<div class="row"> <div class="row">
<div class="col col-12 col-xl-5"> <div class="col col-6">
<div class="card"> <div class="card">
<h5 class="card-header">{% trans "Rack Type" %}</h5> <h5 class="card-header">{% trans "Rack Type" %}</h5>
<table class="table table-hover attr-table"> <table class="table table-hover attr-table">
<tr> <tr>
<th scope="row">{% trans "Description" %}</th> <th scope="row">{% trans "Name" %}</th>
<td>{{ object.description|placeholder }}</td> <td>{{ object.name }}</td>
</tr> </tr>
</table>
</div>
<div class="card">
<h5 class="card-header">{% trans "Dimensions" %}</h5>
<table class="table table-hover attr-table">
<tr> <tr>
<th scope="row">{% trans "Type" %}</th> <th scope="row">{% trans "Type" %}</th>
<td> <td>
@ -31,6 +26,15 @@
{% endif %} {% endif %}
</td> </td>
</tr> </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> <tr>
<th scope="row">{% trans "Width" %}</th> <th scope="row">{% trans "Width" %}</th>
<td>{{ object.get_width_display }}</td> <td>{{ object.get_width_display }}</td>
@ -97,12 +101,12 @@
</tr> </tr>
</table> </table>
</div> </div>
{% include 'inc/panels/custom_fields.html' %}
{% include 'inc/panels/tags.html' %} {% include 'inc/panels/tags.html' %}
{% include 'inc/panels/comments.html' %} {% include 'inc/panels/comments.html' %}
{% plugin_left_page object %} {% plugin_left_page object %}
</div> </div>
<div class="col col-12 col-xl-7"> <div class="col col-6">
{% include 'inc/panels/custom_fields.html' %}
{% include 'inc/panels/related_objects.html' %} {% include 'inc/panels/related_objects.html' %}
{% plugin_right_page object %} {% plugin_right_page object %}
</div> </div>

View File

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