Implemented DeviceType component template creation and deletion

This commit is contained in:
Jeremy Stretch
2016-03-04 23:09:32 -05:00
parent 009ef41e92
commit 61cbee15ca
6 changed files with 237 additions and 86 deletions

View File

@@ -1,7 +1,8 @@
import django_tables2 as tables
from django_tables2.utils import Accessor
from .models import Site, Rack, DeviceType, Device, ConsolePort, PowerPort
from .models import Site, Rack, DeviceType, ConsolePortTemplate, ConsoleServerPortTemplate, PowerPortTemplate, \
PowerOutletTemplate, InterfaceTemplate, Device, ConsolePort, PowerPort
PREFIXES_PER_VLAN = """
@@ -98,6 +99,112 @@ class DeviceTypeBulkEditTable(DeviceTypeTable):
fields = ('pk', 'model', 'manufacturer', 'u_height')
#
# Device type components
#
class ConsolePortTemplateTable(tables.Table):
class Meta:
model = ConsolePortTemplate
fields = ('name',)
empty_text = "None"
show_header = False
attrs = {
'class': 'table table-hover panel-body',
}
class ConsolePortTemplateBulkDeleteTable(ConsolePortTemplateTable):
pk = tables.CheckBoxColumn()
class Meta(ConsolePortTemplateTable.Meta):
model = None # django_tables2 bugfix
fields = ('pk', 'name')
class ConsoleServerPortTemplateTable(tables.Table):
class Meta:
model = ConsoleServerPortTemplate
fields = ('name',)
empty_text = "None"
show_header = False
attrs = {
'class': 'table table-hover panel-body',
}
class ConsoleServerPortTemplateBulkDeleteTable(ConsoleServerPortTemplateTable):
pk = tables.CheckBoxColumn()
class Meta(ConsoleServerPortTemplateTable.Meta):
model = None # django_tables2 bugfix
fields = ('pk', 'name')
class PowerPortTemplateTable(tables.Table):
class Meta:
model = PowerPortTemplate
fields = ('name',)
empty_text = "None"
show_header = False
attrs = {
'class': 'table table-hover panel-body',
}
class PowerPortTemplateBulkDeleteTable(PowerPortTemplateTable):
pk = tables.CheckBoxColumn()
class Meta(PowerPortTemplateTable.Meta):
model = None # django_tables2 bugfix
fields = ('pk', 'name')
class PowerOutletTemplateTable(tables.Table):
class Meta:
model = PowerOutletTemplate
fields = ('name',)
empty_text = "None"
show_header = False
attrs = {
'class': 'table table-hover panel-body',
}
class PowerOutletTemplateBulkDeleteTable(PowerOutletTemplateTable):
pk = tables.CheckBoxColumn()
class Meta(PowerOutletTemplateTable.Meta):
model = None # django_tables2 bugfix
fields = ('pk', 'name')
class InterfaceTemplateTable(tables.Table):
class Meta:
model = InterfaceTemplate
fields = ('name',)
empty_text = "None"
show_header = False
attrs = {
'class': 'table table-hover panel-body',
}
class InterfaceTemplateBulkDeleteTable(InterfaceTemplateTable):
pk = tables.CheckBoxColumn()
class Meta(InterfaceTemplateTable.Meta):
model = None # django_tables2 bugfix
fields = ('pk', 'name')
#
# Devices
#

View File

@@ -3,7 +3,8 @@ from django.conf.urls import url
from secrets.views import secret_add
from . import views
from .forms import ConsolePortTemplateForm
from .models import ConsolePortTemplate, ConsoleServerPortTemplate, PowerPortTemplate, PowerOutletTemplate, \
InterfaceTemplate
urlpatterns = [
@@ -34,16 +35,28 @@ urlpatterns = [
url(r'^device-types/(?P<pk>\d+)/$', views.devicetype, name='devicetype'),
url(r'^device-types/(?P<pk>\d+)/edit/$', views.devicetype_edit, name='devicetype_edit'),
url(r'^device-types/(?P<pk>\d+)/delete/$', views.devicetype_delete, name='devicetype_delete'),
# Component templates
url(r'^device-types/(?P<pk>\d+)/console-ports/add/$', views.ConsolePortTemplateAddView.as_view(),
name='devicetype_add_consoleport'),
url(r'^device-types/(?P<pk>\d+)/console-server-ports/add/$', views.ConsolePortTemplateAddView.as_view(),
url(r'^device-types/(?P<pk>\d+)/console-ports/delete/$', views.component_template_delete,
{'model': ConsolePortTemplate}, name='devicetype_delete_consoleport'),
url(r'^device-types/(?P<pk>\d+)/console-server-ports/add/$', views.ConsoleServerPortTemplateAddView.as_view(),
name='devicetype_add_consoleserverport'),
url(r'^device-types/(?P<pk>\d+)/console-server-ports/delete/$', views.component_template_delete,
{'model': ConsoleServerPortTemplate}, name='devicetype_delete_consoleserverport'),
url(r'^device-types/(?P<pk>\d+)/power-ports/add/$', views.PowerPortTemplateAddView.as_view(),
name='devicetype_add_powerport'),
url(r'^device-types/(?P<pk>\d+)/power-ports/delete/$', views.component_template_delete,
{'model': PowerPortTemplate}, name='devicetype_delete_powerport'),
url(r'^device-types/(?P<pk>\d+)/power-outlets/add/$', views.PowerOutletTemplateAddView.as_view(),
name='devicetype_add_poweroutlet'),
url(r'^device-types/(?P<pk>\d+)/power-outlets/delete/$', views.component_template_delete,
{'model': PowerOutletTemplate}, name='devicetype_delete_poweroutlet'),
url(r'^device-types/(?P<pk>\d+)/interfaces/add/$', views.InterfaceTemplateAddView.as_view(),
name='devicetype_add_interface'),
url(r'^device-types/(?P<pk>\d+)/interfaces/delete/$', views.component_template_delete,
{'model': InterfaceTemplate}, name='devicetype_delete_interface'),
# Devices
url(r'^devices/$', views.DeviceListView.as_view(), name='device_list'),

View File

@@ -6,6 +6,7 @@ from django.contrib.auth.mixins import PermissionRequiredMixin
from django.core.exceptions import ValidationError
from django.core.urlresolvers import reverse
from django.db.models import Count, ProtectedError
from django.forms import ModelMultipleChoiceField, MultipleHiddenInput
from django.http import HttpResponseRedirect
from django.shortcuts import get_object_or_404, redirect, render
from django.utils.http import urlencode
@@ -33,7 +34,10 @@ from .models import Site, Rack, DeviceType, ConsolePortTemplate, ConsoleServerPo
PowerOutletTemplate, InterfaceTemplate, Device, ConsolePort, ConsoleServerPort, PowerPort, PowerOutlet, Interface, \
InterfaceConnection, Module, CONNECTION_STATUS_CONNECTED
from .tables import SiteTable, RackTable, RackBulkEditTable, DeviceTypeTable, DeviceTypeBulkEditTable, DeviceTable, \
DeviceBulkEditTable, DeviceImportTable, ConsoleConnectionTable, PowerConnectionTable, InterfaceConnectionTable
DeviceBulkEditTable, DeviceImportTable, ConsoleConnectionTable, PowerConnectionTable, InterfaceConnectionTable, \
ConsolePortTemplateTable, ConsoleServerPortTemplateTable, PowerPortTemplateTable, PowerOutletTemplateTable, \
InterfaceTemplateTable, ConsolePortTemplateBulkDeleteTable, ConsoleServerPortTemplateBulkDeleteTable, \
PowerPortTemplateBulkDeleteTable, PowerOutletTemplateBulkDeleteTable, InterfaceTemplateBulkDeleteTable
EXPANSION_PATTERN = '\[(\d+-\d+)\]'
@@ -331,8 +335,27 @@ def devicetype(request, pk):
devicetype = get_object_or_404(DeviceType, pk=pk)
# Component tables
if request.user.has_perm('dcim.change_devicetype'):
consoleport_table = ConsolePortTemplateBulkDeleteTable(ConsolePortTemplate.objects.filter(device_type=devicetype))
consoleserverport_table = ConsoleServerPortTemplateBulkDeleteTable(ConsoleServerPortTemplate.objects.filter(device_type=devicetype))
powerport_table = PowerPortTemplateBulkDeleteTable(PowerPortTemplate.objects.filter(device_type=devicetype))
poweroutlet_table = PowerOutletTemplateBulkDeleteTable(PowerOutletTemplate.objects.filter(device_type=devicetype))
interface_table = InterfaceTemplateBulkDeleteTable(InterfaceTemplate.objects.filter(device_type=devicetype))
else:
consoleport_table = ConsolePortTemplateTable(ConsolePortTemplate.objects.filter(device_type=devicetype))
consoleserverport_table = ConsoleServerPortTemplateTable(ConsoleServerPortTemplate.objects.filter(device_type=devicetype))
powerport_table = PowerPortTemplateTable(PowerPortTemplate.objects.filter(device_type=devicetype))
poweroutlet_table = PowerOutletTemplateTable(PowerOutletTemplate.objects.filter(device_type=devicetype))
interface_table = InterfaceTemplateTable(InterfaceTemplate.objects.filter(device_type=devicetype))
return render(request, 'dcim/devicetype.html', {
'devicetype': devicetype,
'consoleport_table': consoleport_table,
'consoleserverport_table': consoleserverport_table,
'powerport_table': powerport_table,
'poweroutlet_table': poweroutlet_table,
'interface_table': interface_table,
})
@@ -432,6 +455,10 @@ class DeviceTypeBulkDeleteView(PermissionRequiredMixin, BulkDeleteView):
redirect_url = 'dcim:devicetype_list'
#
# Device type components
#
class ComponentTemplateCreateView(View):
model = None
form = None
@@ -506,6 +533,45 @@ class InterfaceTemplateAddView(ComponentTemplateCreateView):
form = InterfaceTemplateForm
def component_template_delete(request, pk, model):
devicetype = get_object_or_404(DeviceType, pk=pk)
class ComponentTemplateBulkDeleteForm(ConfirmationForm):
pk = ModelMultipleChoiceField(queryset=model.objects.all(), widget=MultipleHiddenInput)
if '_confirm' in request.POST:
form = ComponentTemplateBulkDeleteForm(request.POST)
if form.is_valid():
# Delete component templates
objects_to_delete = model.objects.filter(pk__in=[v.id for v in form.cleaned_data['pk']])
try:
deleted_count = objects_to_delete.count()
objects_to_delete.delete()
except ProtectedError, e:
handle_protectederror(list(objects_to_delete), request, e)
return redirect('dcim:devicetype', {'pk': devicetype.pk})
messages.success(request, "Deleted {} {}".format(deleted_count, model._meta.verbose_name_plural))
return redirect('dcim:devicetype', pk=devicetype.pk)
else:
form = ComponentTemplateBulkDeleteForm(initial={'pk': request.POST.getlist('pk')})
selected_objects = model.objects.filter(pk__in=form.initial.get('pk'))
if not selected_objects:
messages.warning(request, "No {} were selected for deletion.".format(model._meta.verbose_name_plural))
return redirect('dcim:devicetype', pk=devicetype.pk)
return render(request, 'dcim/component_template_delete.html', {
'devicetype': devicetype,
'form': form,
'selected_objects': selected_objects,
'cancel_url': reverse('dcim:devicetype', kwargs={'pk': devicetype.pk}),
})
#
# Devices
#