mirror of
https://github.com/netbox-community/netbox.git
synced 2025-08-09 00:58:16 -06:00
12826 add forms, filters, tables
This commit is contained in:
parent
21e11cd78f
commit
24b957aab4
@ -69,6 +69,7 @@ __all__ = (
|
|||||||
'RackFilterSet',
|
'RackFilterSet',
|
||||||
'RackReservationFilterSet',
|
'RackReservationFilterSet',
|
||||||
'RackRoleFilterSet',
|
'RackRoleFilterSet',
|
||||||
|
'RackTypeFilterSet',
|
||||||
'RearPortFilterSet',
|
'RearPortFilterSet',
|
||||||
'RearPortTemplateFilterSet',
|
'RearPortTemplateFilterSet',
|
||||||
'RegionFilterSet',
|
'RegionFilterSet',
|
||||||
@ -289,6 +290,41 @@ class RackRoleFilterSet(OrganizationalModelFilterSet):
|
|||||||
fields = ('id', 'name', 'slug', 'color', 'description')
|
fields = ('id', 'name', 'slug', 'color', 'description')
|
||||||
|
|
||||||
|
|
||||||
|
class RackTypeFilterSet(NetBoxModelFilterSet):
|
||||||
|
type = django_filters.MultipleChoiceFilter(
|
||||||
|
choices=RackTypeChoices
|
||||||
|
)
|
||||||
|
width = django_filters.MultipleChoiceFilter(
|
||||||
|
choices=RackWidthChoices
|
||||||
|
)
|
||||||
|
role_id = django_filters.ModelMultipleChoiceFilter(
|
||||||
|
queryset=RackRole.objects.all(),
|
||||||
|
label=_('Role (ID)'),
|
||||||
|
)
|
||||||
|
role = django_filters.ModelMultipleChoiceFilter(
|
||||||
|
field_name='role__slug',
|
||||||
|
queryset=RackRole.objects.all(),
|
||||||
|
to_field_name='slug',
|
||||||
|
label=_('Role (slug)'),
|
||||||
|
)
|
||||||
|
|
||||||
|
class Meta:
|
||||||
|
model = Rack
|
||||||
|
fields = (
|
||||||
|
'id', 'name', 'u_height', 'starting_unit', 'desc_units', 'outer_width',
|
||||||
|
'outer_depth', 'outer_unit', 'mounting_depth', 'weight', 'max_weight', 'weight_unit', 'description',
|
||||||
|
)
|
||||||
|
|
||||||
|
def search(self, queryset, name, value):
|
||||||
|
if not value.strip():
|
||||||
|
return queryset
|
||||||
|
return queryset.filter(
|
||||||
|
Q(name__icontains=value) |
|
||||||
|
Q(description__icontains=value) |
|
||||||
|
Q(comments__icontains=value)
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
class RackFilterSet(NetBoxModelFilterSet, TenancyFilterSet, ContactModelFilterSet):
|
class RackFilterSet(NetBoxModelFilterSet, TenancyFilterSet, ContactModelFilterSet):
|
||||||
region_id = TreeNodeMultipleChoiceFilter(
|
region_id = TreeNodeMultipleChoiceFilter(
|
||||||
queryset=Region.objects.all(),
|
queryset=Region.objects.all(),
|
||||||
|
@ -52,6 +52,7 @@ __all__ = (
|
|||||||
'RackBulkEditForm',
|
'RackBulkEditForm',
|
||||||
'RackReservationBulkEditForm',
|
'RackReservationBulkEditForm',
|
||||||
'RackRoleBulkEditForm',
|
'RackRoleBulkEditForm',
|
||||||
|
'RackTypeBulkEditForm',
|
||||||
'RearPortBulkEditForm',
|
'RearPortBulkEditForm',
|
||||||
'RearPortTemplateBulkEditForm',
|
'RearPortTemplateBulkEditForm',
|
||||||
'RegionBulkEditForm',
|
'RegionBulkEditForm',
|
||||||
@ -218,6 +219,89 @@ class RackRoleBulkEditForm(NetBoxModelBulkEditForm):
|
|||||||
nullable_fields = ('color', 'description')
|
nullable_fields = ('color', 'description')
|
||||||
|
|
||||||
|
|
||||||
|
class RackTypeBulkEditForm(NetBoxModelBulkEditForm):
|
||||||
|
role = DynamicModelChoiceField(
|
||||||
|
label=_('Role'),
|
||||||
|
queryset=RackRole.objects.all(),
|
||||||
|
required=False
|
||||||
|
)
|
||||||
|
type = forms.ChoiceField(
|
||||||
|
label=_('Type'),
|
||||||
|
choices=add_blank_choice(RackTypeChoices),
|
||||||
|
required=False
|
||||||
|
)
|
||||||
|
width = forms.ChoiceField(
|
||||||
|
label=_('Width'),
|
||||||
|
choices=add_blank_choice(RackWidthChoices),
|
||||||
|
required=False
|
||||||
|
)
|
||||||
|
u_height = forms.IntegerField(
|
||||||
|
required=False,
|
||||||
|
label=_('Height (U)')
|
||||||
|
)
|
||||||
|
desc_units = forms.NullBooleanField(
|
||||||
|
required=False,
|
||||||
|
widget=BulkEditNullBooleanSelect,
|
||||||
|
label=_('Descending units')
|
||||||
|
)
|
||||||
|
outer_width = forms.IntegerField(
|
||||||
|
label=_('Outer width'),
|
||||||
|
required=False,
|
||||||
|
min_value=1
|
||||||
|
)
|
||||||
|
outer_depth = forms.IntegerField(
|
||||||
|
label=_('Outer depth'),
|
||||||
|
required=False,
|
||||||
|
min_value=1
|
||||||
|
)
|
||||||
|
outer_unit = forms.ChoiceField(
|
||||||
|
label=_('Outer unit'),
|
||||||
|
choices=add_blank_choice(RackDimensionUnitChoices),
|
||||||
|
required=False
|
||||||
|
)
|
||||||
|
mounting_depth = forms.IntegerField(
|
||||||
|
label=_('Mounting depth'),
|
||||||
|
required=False,
|
||||||
|
min_value=1
|
||||||
|
)
|
||||||
|
weight = forms.DecimalField(
|
||||||
|
label=_('Weight'),
|
||||||
|
min_value=0,
|
||||||
|
required=False
|
||||||
|
)
|
||||||
|
max_weight = forms.IntegerField(
|
||||||
|
label=_('Max weight'),
|
||||||
|
min_value=0,
|
||||||
|
required=False
|
||||||
|
)
|
||||||
|
weight_unit = forms.ChoiceField(
|
||||||
|
label=_('Weight unit'),
|
||||||
|
choices=add_blank_choice(WeightUnitChoices),
|
||||||
|
required=False,
|
||||||
|
initial=''
|
||||||
|
)
|
||||||
|
description = forms.CharField(
|
||||||
|
label=_('Description'),
|
||||||
|
max_length=200,
|
||||||
|
required=False
|
||||||
|
)
|
||||||
|
comments = CommentField()
|
||||||
|
|
||||||
|
model = Rack
|
||||||
|
fieldsets = (
|
||||||
|
FieldSet('role', 'description', name=_('Rack')),
|
||||||
|
FieldSet(
|
||||||
|
'type', 'width', 'u_height', 'desc_units', 'outer_width', 'outer_depth', 'outer_unit', 'mounting_depth',
|
||||||
|
name=_('Hardware')
|
||||||
|
),
|
||||||
|
FieldSet('weight', 'max_weight', 'weight_unit', name=_('Weight')),
|
||||||
|
)
|
||||||
|
nullable_fields = (
|
||||||
|
'role', 'outer_width', 'outer_depth', 'outer_unit', 'weight',
|
||||||
|
'max_weight', 'weight_unit', 'description', 'comments',
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
class RackBulkEditForm(NetBoxModelBulkEditForm):
|
class RackBulkEditForm(NetBoxModelBulkEditForm):
|
||||||
region = DynamicModelChoiceField(
|
region = DynamicModelChoiceField(
|
||||||
label=_('Region'),
|
label=_('Region'),
|
||||||
|
@ -45,6 +45,7 @@ __all__ = (
|
|||||||
'RackImportForm',
|
'RackImportForm',
|
||||||
'RackReservationImportForm',
|
'RackReservationImportForm',
|
||||||
'RackRoleImportForm',
|
'RackRoleImportForm',
|
||||||
|
'RackTypeImportForm',
|
||||||
'RearPortImportForm',
|
'RearPortImportForm',
|
||||||
'RegionImportForm',
|
'RegionImportForm',
|
||||||
'SiteImportForm',
|
'SiteImportForm',
|
||||||
@ -179,6 +180,50 @@ class RackRoleImportForm(NetBoxModelImportForm):
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
class RackTypeImportForm(NetBoxModelImportForm):
|
||||||
|
role = CSVModelChoiceField(
|
||||||
|
label=_('Role'),
|
||||||
|
queryset=RackRole.objects.all(),
|
||||||
|
required=False,
|
||||||
|
to_field_name='name',
|
||||||
|
help_text=_('Name of assigned role')
|
||||||
|
)
|
||||||
|
type = CSVChoiceField(
|
||||||
|
label=_('Type'),
|
||||||
|
choices=RackTypeChoices,
|
||||||
|
required=False,
|
||||||
|
help_text=_('Rack type')
|
||||||
|
)
|
||||||
|
width = forms.ChoiceField(
|
||||||
|
label=_('Width'),
|
||||||
|
choices=RackWidthChoices,
|
||||||
|
help_text=_('Rail-to-rail width (in inches)')
|
||||||
|
)
|
||||||
|
outer_unit = CSVChoiceField(
|
||||||
|
label=_('Outer unit'),
|
||||||
|
choices=RackDimensionUnitChoices,
|
||||||
|
required=False,
|
||||||
|
help_text=_('Unit for outer dimensions')
|
||||||
|
)
|
||||||
|
weight_unit = CSVChoiceField(
|
||||||
|
label=_('Weight unit'),
|
||||||
|
choices=WeightUnitChoices,
|
||||||
|
required=False,
|
||||||
|
help_text=_('Unit for rack weights')
|
||||||
|
)
|
||||||
|
|
||||||
|
class Meta:
|
||||||
|
model = RackType
|
||||||
|
fields = (
|
||||||
|
'name', 'role', 'type',
|
||||||
|
'width', 'u_height', 'desc_units', 'outer_width', 'outer_depth', 'outer_unit', 'mounting_depth', 'weight',
|
||||||
|
'max_weight', 'weight_unit', 'description', 'comments', 'tags',
|
||||||
|
)
|
||||||
|
|
||||||
|
def __init__(self, data=None, *args, **kwargs):
|
||||||
|
super().__init__(data, *args, **kwargs)
|
||||||
|
|
||||||
|
|
||||||
class RackImportForm(NetBoxModelImportForm):
|
class RackImportForm(NetBoxModelImportForm):
|
||||||
site = CSVModelChoiceField(
|
site = CSVModelChoiceField(
|
||||||
label=_('Site'),
|
label=_('Site'),
|
||||||
|
@ -47,6 +47,7 @@ __all__ = (
|
|||||||
'RackElevationFilterForm',
|
'RackElevationFilterForm',
|
||||||
'RackReservationFilterForm',
|
'RackReservationFilterForm',
|
||||||
'RackRoleFilterForm',
|
'RackRoleFilterForm',
|
||||||
|
'RackTypeFilterForm',
|
||||||
'RearPortFilterForm',
|
'RearPortFilterForm',
|
||||||
'RegionFilterForm',
|
'RegionFilterForm',
|
||||||
'SiteFilterForm',
|
'SiteFilterForm',
|
||||||
@ -239,6 +240,53 @@ class RackRoleFilterForm(NetBoxModelFilterSetForm):
|
|||||||
tag = TagFilterField(model)
|
tag = TagFilterField(model)
|
||||||
|
|
||||||
|
|
||||||
|
class RackTypeFilterForm(NetBoxModelFilterSetForm):
|
||||||
|
model = Rack
|
||||||
|
fieldsets = (
|
||||||
|
FieldSet('q', 'filter_id', 'tag'),
|
||||||
|
FieldSet('role_id', name=_('Function')),
|
||||||
|
FieldSet('type', 'width', 'serial', name=_('Hardware')),
|
||||||
|
FieldSet('weight', 'max_weight', 'weight_unit', name=_('Weight')),
|
||||||
|
)
|
||||||
|
selector_fields = ('filter_id', 'q',)
|
||||||
|
type = forms.MultipleChoiceField(
|
||||||
|
label=_('Type'),
|
||||||
|
choices=RackTypeChoices,
|
||||||
|
required=False
|
||||||
|
)
|
||||||
|
width = forms.MultipleChoiceField(
|
||||||
|
label=_('Width'),
|
||||||
|
choices=RackWidthChoices,
|
||||||
|
required=False
|
||||||
|
)
|
||||||
|
role_id = DynamicModelMultipleChoiceField(
|
||||||
|
queryset=RackRole.objects.all(),
|
||||||
|
required=False,
|
||||||
|
null_option='None',
|
||||||
|
label=_('Role')
|
||||||
|
)
|
||||||
|
serial = forms.CharField(
|
||||||
|
label=_('Serial'),
|
||||||
|
required=False
|
||||||
|
)
|
||||||
|
tag = TagFilterField(model)
|
||||||
|
weight = forms.DecimalField(
|
||||||
|
label=_('Weight'),
|
||||||
|
required=False,
|
||||||
|
min_value=1
|
||||||
|
)
|
||||||
|
max_weight = forms.IntegerField(
|
||||||
|
label=_('Max weight'),
|
||||||
|
required=False,
|
||||||
|
min_value=1
|
||||||
|
)
|
||||||
|
weight_unit = forms.ChoiceField(
|
||||||
|
label=_('Weight unit'),
|
||||||
|
choices=add_blank_choice(WeightUnitChoices),
|
||||||
|
required=False
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
class RackFilterForm(TenancyFilterForm, ContactModelFilterForm, NetBoxModelFilterSetForm):
|
class RackFilterForm(TenancyFilterForm, ContactModelFilterForm, NetBoxModelFilterSetForm):
|
||||||
model = Rack
|
model = Rack
|
||||||
fieldsets = (
|
fieldsets = (
|
||||||
|
@ -57,6 +57,7 @@ __all__ = (
|
|||||||
'RackForm',
|
'RackForm',
|
||||||
'RackReservationForm',
|
'RackReservationForm',
|
||||||
'RackRoleForm',
|
'RackRoleForm',
|
||||||
|
'RackTypeForm',
|
||||||
'RearPortForm',
|
'RearPortForm',
|
||||||
'RearPortTemplateForm',
|
'RearPortTemplateForm',
|
||||||
'RegionForm',
|
'RegionForm',
|
||||||
@ -201,6 +202,33 @@ class RackRoleForm(NetBoxModelForm):
|
|||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
|
class RackTypeForm(NetBoxModelForm):
|
||||||
|
role = DynamicModelChoiceField(
|
||||||
|
label=_('Role'),
|
||||||
|
queryset=RackRole.objects.all(),
|
||||||
|
required=False
|
||||||
|
)
|
||||||
|
comments = CommentField()
|
||||||
|
|
||||||
|
fieldsets = (
|
||||||
|
FieldSet('name', 'status', 'role', 'description', 'tags', name=_('Rack')),
|
||||||
|
FieldSet(
|
||||||
|
'type', 'width', 'starting_unit', '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')
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
|
class Meta:
|
||||||
|
model = Rack
|
||||||
|
fields = [
|
||||||
|
'name', 'role',
|
||||||
|
'type', 'width', 'u_height', 'starting_unit', 'desc_units', 'outer_width', 'outer_depth',
|
||||||
|
'outer_unit', 'mounting_depth', 'weight', 'max_weight', 'weight_unit', 'description', 'comments', 'tags',
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
class RackForm(TenancyForm, NetBoxModelForm):
|
class RackForm(TenancyForm, NetBoxModelForm):
|
||||||
site = DynamicModelChoiceField(
|
site = DynamicModelChoiceField(
|
||||||
label=_('Site'),
|
label=_('Site'),
|
||||||
|
@ -2,7 +2,7 @@ from django.utils.translation import gettext_lazy as _
|
|||||||
import django_tables2 as tables
|
import django_tables2 as tables
|
||||||
from django_tables2.utils import Accessor
|
from django_tables2.utils import Accessor
|
||||||
|
|
||||||
from dcim.models import Rack, RackReservation, RackRole
|
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 WEIGHT
|
||||||
@ -11,6 +11,7 @@ __all__ = (
|
|||||||
'RackTable',
|
'RackTable',
|
||||||
'RackReservationTable',
|
'RackReservationTable',
|
||||||
'RackRoleTable',
|
'RackRoleTable',
|
||||||
|
'RackTypeTable',
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@ -44,6 +45,61 @@ class RackRoleTable(NetBoxTable):
|
|||||||
default_columns = ('pk', 'name', 'rack_count', 'color', 'description')
|
default_columns = ('pk', 'name', 'rack_count', 'color', 'description')
|
||||||
|
|
||||||
|
|
||||||
|
#
|
||||||
|
# Rack Types
|
||||||
|
#
|
||||||
|
|
||||||
|
class RackTypeTable(NetBoxTable):
|
||||||
|
name = tables.Column(
|
||||||
|
verbose_name=_('Name'),
|
||||||
|
order_by=('_name',),
|
||||||
|
linkify=True
|
||||||
|
)
|
||||||
|
role = columns.ColoredLabelColumn(
|
||||||
|
verbose_name=_('Role'),
|
||||||
|
)
|
||||||
|
u_height = tables.TemplateColumn(
|
||||||
|
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')
|
||||||
|
)
|
||||||
|
outer_depth = tables.TemplateColumn(
|
||||||
|
template_code="{{ record.outer_depth }} {{ record.outer_unit }}",
|
||||||
|
verbose_name=_('Outer Depth')
|
||||||
|
)
|
||||||
|
weight = columns.TemplateColumn(
|
||||||
|
verbose_name=_('Weight'),
|
||||||
|
template_code=WEIGHT,
|
||||||
|
order_by=('_abs_weight', 'weight_unit')
|
||||||
|
)
|
||||||
|
max_weight = columns.TemplateColumn(
|
||||||
|
verbose_name=_('Max Weight'),
|
||||||
|
template_code=WEIGHT,
|
||||||
|
order_by=('_abs_max_weight', 'weight_unit')
|
||||||
|
)
|
||||||
|
|
||||||
|
class Meta(NetBoxTable.Meta):
|
||||||
|
model = RackType
|
||||||
|
fields = (
|
||||||
|
'pk', 'id', 'name', 'role',
|
||||||
|
'type', 'u_height', 'starting_unit', 'width', 'outer_width', 'outer_depth', 'mounting_depth',
|
||||||
|
'weight', 'max_weight', 'comments',
|
||||||
|
'description', 'tags', 'created', 'last_updated',
|
||||||
|
)
|
||||||
|
default_columns = (
|
||||||
|
'pk', 'name', 'role', 'u_height',
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
#
|
#
|
||||||
# Racks
|
# Racks
|
||||||
#
|
#
|
||||||
|
@ -63,6 +63,14 @@ urlpatterns = [
|
|||||||
path('racks/delete/', views.RackBulkDeleteView.as_view(), name='rack_bulk_delete'),
|
path('racks/delete/', views.RackBulkDeleteView.as_view(), name='rack_bulk_delete'),
|
||||||
path('racks/<int:pk>/', include(get_model_urls('dcim', 'rack'))),
|
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'))),
|
||||||
|
|
||||||
# Manufacturers
|
# Manufacturers
|
||||||
path('manufacturers/', views.ManufacturerListView.as_view(), name='manufacturer_list'),
|
path('manufacturers/', views.ManufacturerListView.as_view(), name='manufacturer_list'),
|
||||||
path('manufacturers/add/', views.ManufacturerEditView.as_view(), name='manufacturer_add'),
|
path('manufacturers/add/', views.ManufacturerEditView.as_view(), name='manufacturer_add'),
|
||||||
|
@ -578,6 +578,52 @@ class RackRoleBulkDeleteView(generic.BulkDeleteView):
|
|||||||
table = tables.RackRoleTable
|
table = tables.RackRoleTable
|
||||||
|
|
||||||
|
|
||||||
|
#
|
||||||
|
# RackTypes
|
||||||
|
#
|
||||||
|
|
||||||
|
class RackTypeListView(generic.ObjectListView):
|
||||||
|
queryset = RackType.objects.all()
|
||||||
|
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 = Rack.objects.prefetch_related('role')
|
||||||
|
|
||||||
|
|
||||||
|
@register_model_view(RackType, 'edit')
|
||||||
|
class RackTypeEditView(generic.ObjectEditView):
|
||||||
|
queryset = RackType.objects.all()
|
||||||
|
form = forms.RackTypeForm
|
||||||
|
|
||||||
|
|
||||||
|
@register_model_view(RackType, 'delete')
|
||||||
|
class RackTypeDeleteView(generic.ObjectDeleteView):
|
||||||
|
queryset = RackType.objects.all()
|
||||||
|
|
||||||
|
|
||||||
|
class RackTypeBulkImportView(generic.BulkImportView):
|
||||||
|
queryset = RackType.objects.all()
|
||||||
|
model_form = forms.RackTypeImportForm
|
||||||
|
|
||||||
|
|
||||||
|
class RackTypeBulkEditView(generic.BulkEditView):
|
||||||
|
queryset = RackType.objects.all()
|
||||||
|
filterset = filtersets.RackTypeFilterSet
|
||||||
|
table = tables.RackTypeTable
|
||||||
|
form = forms.RackTypeBulkEditForm
|
||||||
|
|
||||||
|
|
||||||
|
class RackTypeBulkDeleteView(generic.BulkDeleteView):
|
||||||
|
queryset = RackType.objects.all()
|
||||||
|
filterset = filtersets.RackTypeFilterSet
|
||||||
|
table = tables.RackTypeTable
|
||||||
|
|
||||||
|
|
||||||
#
|
#
|
||||||
# Racks
|
# Racks
|
||||||
#
|
#
|
||||||
|
Loading…
Reference in New Issue
Block a user