mirror of
https://github.com/netbox-community/netbox.git
synced 2025-07-16 12:12:53 -06:00
Implemented DeviceType component template creation and deletion
This commit is contained in:
parent
009ef41e92
commit
61cbee15ca
@ -1,7 +1,8 @@
|
|||||||
import django_tables2 as tables
|
import django_tables2 as tables
|
||||||
from django_tables2.utils import Accessor
|
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 = """
|
PREFIXES_PER_VLAN = """
|
||||||
@ -98,6 +99,112 @@ class DeviceTypeBulkEditTable(DeviceTypeTable):
|
|||||||
fields = ('pk', 'model', 'manufacturer', 'u_height')
|
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
|
# Devices
|
||||||
#
|
#
|
||||||
|
@ -3,7 +3,8 @@ from django.conf.urls import url
|
|||||||
from secrets.views import secret_add
|
from secrets.views import secret_add
|
||||||
|
|
||||||
from . import views
|
from . import views
|
||||||
from .forms import ConsolePortTemplateForm
|
from .models import ConsolePortTemplate, ConsoleServerPortTemplate, PowerPortTemplate, PowerOutletTemplate, \
|
||||||
|
InterfaceTemplate
|
||||||
|
|
||||||
|
|
||||||
urlpatterns = [
|
urlpatterns = [
|
||||||
@ -34,16 +35,28 @@ urlpatterns = [
|
|||||||
url(r'^device-types/(?P<pk>\d+)/$', views.devicetype, name='devicetype'),
|
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+)/edit/$', views.devicetype_edit, name='devicetype_edit'),
|
||||||
url(r'^device-types/(?P<pk>\d+)/delete/$', views.devicetype_delete, name='devicetype_delete'),
|
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(),
|
url(r'^device-types/(?P<pk>\d+)/console-ports/add/$', views.ConsolePortTemplateAddView.as_view(),
|
||||||
name='devicetype_add_consoleport'),
|
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'),
|
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(),
|
url(r'^device-types/(?P<pk>\d+)/power-ports/add/$', views.PowerPortTemplateAddView.as_view(),
|
||||||
name='devicetype_add_powerport'),
|
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(),
|
url(r'^device-types/(?P<pk>\d+)/power-outlets/add/$', views.PowerOutletTemplateAddView.as_view(),
|
||||||
name='devicetype_add_poweroutlet'),
|
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(),
|
url(r'^device-types/(?P<pk>\d+)/interfaces/add/$', views.InterfaceTemplateAddView.as_view(),
|
||||||
name='devicetype_add_interface'),
|
name='devicetype_add_interface'),
|
||||||
|
url(r'^device-types/(?P<pk>\d+)/interfaces/delete/$', views.component_template_delete,
|
||||||
|
{'model': InterfaceTemplate}, name='devicetype_delete_interface'),
|
||||||
|
|
||||||
# Devices
|
# Devices
|
||||||
url(r'^devices/$', views.DeviceListView.as_view(), name='device_list'),
|
url(r'^devices/$', views.DeviceListView.as_view(), name='device_list'),
|
||||||
|
@ -6,6 +6,7 @@ from django.contrib.auth.mixins import PermissionRequiredMixin
|
|||||||
from django.core.exceptions import ValidationError
|
from django.core.exceptions import ValidationError
|
||||||
from django.core.urlresolvers import reverse
|
from django.core.urlresolvers import reverse
|
||||||
from django.db.models import Count, ProtectedError
|
from django.db.models import Count, ProtectedError
|
||||||
|
from django.forms import ModelMultipleChoiceField, MultipleHiddenInput
|
||||||
from django.http import HttpResponseRedirect
|
from django.http import HttpResponseRedirect
|
||||||
from django.shortcuts import get_object_or_404, redirect, render
|
from django.shortcuts import get_object_or_404, redirect, render
|
||||||
from django.utils.http import urlencode
|
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, \
|
PowerOutletTemplate, InterfaceTemplate, Device, ConsolePort, ConsoleServerPort, PowerPort, PowerOutlet, Interface, \
|
||||||
InterfaceConnection, Module, CONNECTION_STATUS_CONNECTED
|
InterfaceConnection, Module, CONNECTION_STATUS_CONNECTED
|
||||||
from .tables import SiteTable, RackTable, RackBulkEditTable, DeviceTypeTable, DeviceTypeBulkEditTable, DeviceTable, \
|
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+)\]'
|
EXPANSION_PATTERN = '\[(\d+-\d+)\]'
|
||||||
@ -331,8 +335,27 @@ def devicetype(request, pk):
|
|||||||
|
|
||||||
devicetype = get_object_or_404(DeviceType, pk=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', {
|
return render(request, 'dcim/devicetype.html', {
|
||||||
'devicetype': devicetype,
|
'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'
|
redirect_url = 'dcim:devicetype_list'
|
||||||
|
|
||||||
|
|
||||||
|
#
|
||||||
|
# Device type components
|
||||||
|
#
|
||||||
|
|
||||||
class ComponentTemplateCreateView(View):
|
class ComponentTemplateCreateView(View):
|
||||||
model = None
|
model = None
|
||||||
form = None
|
form = None
|
||||||
@ -506,6 +533,45 @@ class InterfaceTemplateAddView(ComponentTemplateCreateView):
|
|||||||
form = InterfaceTemplateForm
|
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
|
# Devices
|
||||||
#
|
#
|
||||||
|
13
netbox/templates/dcim/component_template_delete.html
Normal file
13
netbox/templates/dcim/component_template_delete.html
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
{% extends 'utilities/confirmation_form.html' %}
|
||||||
|
{% load form_helpers %}
|
||||||
|
|
||||||
|
{% block title %}Delete devie type components?{% endblock %}
|
||||||
|
|
||||||
|
{% block message %}
|
||||||
|
<p>Are you sure you want to delete these components from <strong>{{ devicetype }}</strong>?</p>
|
||||||
|
<ul>
|
||||||
|
{% for o in selected_objects %}
|
||||||
|
<li>{{ o }}</li>
|
||||||
|
{% endfor %}
|
||||||
|
</ul>
|
||||||
|
{% endblock %}
|
@ -73,90 +73,13 @@
|
|||||||
</tr>
|
</tr>
|
||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
<div class="panel panel-default">
|
{% include 'dcim/inc/devicetype_component_table.html' with table=consoleport_table title='Console Ports' add_url='dcim:devicetype_add_consoleport' delete_url='dcim:devicetype_delete_consoleport' %}
|
||||||
<div class="panel-heading">
|
{% include 'dcim/inc/devicetype_component_table.html' with table=powerport_table title='Power Ports' add_url='dcim:devicetype_add_powerport' delete_url='dcim:devicetype_delete_powerport' %}
|
||||||
{% if perms.dcim.change_devicetype %}
|
|
||||||
<a href="{% url 'dcim:devicetype_add_consoleport' pk=devicetype.pk %}" class="btn btn-primary btn-xs pull-right"><span class="glyphicon glyphicon-plus" aria-hidden="true"></span> Add Console Ports</a>
|
|
||||||
{% endif %}
|
|
||||||
<strong>Console Ports</strong>
|
|
||||||
</div>
|
|
||||||
<table class="table table-hover panel-body">
|
|
||||||
{% for cp in devicetype.console_port_templates.all %}
|
|
||||||
<tr>
|
|
||||||
<td>{{ cp.name }}</td>
|
|
||||||
<td></td>
|
|
||||||
</tr>
|
|
||||||
{% endfor %}
|
|
||||||
</table>
|
|
||||||
</div>
|
|
||||||
<div class="panel panel-default">
|
|
||||||
<div class="panel-heading">
|
|
||||||
{% if perms.dcim.change_devicetype %}
|
|
||||||
<a href="{% url 'dcim:devicetype_add_powerport' pk=devicetype.pk %}" class="btn btn-primary btn-xs pull-right"><span class="glyphicon glyphicon-plus" aria-hidden="true"></span> Add Power Ports</a>
|
|
||||||
{% endif %}
|
|
||||||
<strong>Power Ports</strong>
|
|
||||||
</div>
|
|
||||||
<table class="table table-hover panel-body">
|
|
||||||
{% for pp in devicetype.power_port_templates.all %}
|
|
||||||
<tr>
|
|
||||||
<td>{{ pp.name }}</td>
|
|
||||||
<td></td>
|
|
||||||
</tr>
|
|
||||||
{% endfor %}
|
|
||||||
</table>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
<div class="col-md-6">
|
<div class="col-md-6">
|
||||||
<div class="panel panel-default">
|
{% include 'dcim/inc/devicetype_component_table.html' with table=interface_table title='Interfaces' add_url='dcim:devicetype_add_interface' delete_url='dcim:devicetype_delete_interface' %}
|
||||||
<div class="panel-heading">
|
{% include 'dcim/inc/devicetype_component_table.html' with table=consoleserverport_table title='Console Server Ports' add_url='dcim:devicetype_add_consoleserverport' delete_url='dcim:devicetype_delete_consoleserverport' %}
|
||||||
{% if perms.dcim.change_devicetype %}
|
{% include 'dcim/inc/devicetype_component_table.html' with table=poweroutlet_table title='Power Outlets' add_url='dcim:devicetype_add_poweroutlet' delete_url='dcim:devicetype_delete_poweroutlet' %}
|
||||||
<a href="{% url 'dcim:devicetype_add_interface' pk=devicetype.pk %}" class="btn btn-primary btn-xs pull-right"><span class="glyphicon glyphicon-plus" aria-hidden="true"></span> Add Interfaces</a>
|
|
||||||
{% endif %}
|
|
||||||
<strong>Interfaces</strong>
|
|
||||||
</div>
|
|
||||||
<table class="table table-hover panel-body">
|
|
||||||
{% for iface in devicetype.interface_templates.all %}
|
|
||||||
<tr>
|
|
||||||
<td>{{ iface.name }}</td>
|
|
||||||
<td>{{ iface.get_form_factor_display }}</td>
|
|
||||||
<td>{{ iface.mgmt_only|yesno|capfirst }}</td>
|
|
||||||
<td></td>
|
|
||||||
</tr>
|
|
||||||
{% endfor %}
|
|
||||||
</table>
|
|
||||||
</div>
|
|
||||||
<div class="panel panel-default">
|
|
||||||
<div class="panel-heading">
|
|
||||||
{% if perms.dcim.change_devicetype %}
|
|
||||||
<a href="{% url 'dcim:devicetype_add_consoleserverport' pk=devicetype.pk %}" class="btn btn-primary btn-xs pull-right"><span class="glyphicon glyphicon-plus" aria-hidden="true"></span> Add Console Server Ports</a>
|
|
||||||
{% endif %}
|
|
||||||
<strong>Console Server Ports</strong>
|
|
||||||
</div>
|
|
||||||
<table class="table table-hover panel-body">
|
|
||||||
{% for csp in devicetype.cs_port_templates.all %}
|
|
||||||
<tr>
|
|
||||||
<td>{{ csp.name }}</td>
|
|
||||||
<td></td>
|
|
||||||
</tr>
|
|
||||||
{% endfor %}
|
|
||||||
</table>
|
|
||||||
</div>
|
|
||||||
<div class="panel panel-default">
|
|
||||||
<div class="panel-heading">
|
|
||||||
{% if perms.dcim.change_devicetype %}
|
|
||||||
<a href="{% url 'dcim:devicetype_add_poweroutlet' pk=devicetype.pk %}" class="btn btn-primary btn-xs pull-right"><span class="glyphicon glyphicon-plus" aria-hidden="true"></span> Add Power Outlet</a>
|
|
||||||
{% endif %}
|
|
||||||
<strong>Power Outlets</strong>
|
|
||||||
</div>
|
|
||||||
<table class="table table-hover panel-body">
|
|
||||||
{% for po in devicetype.power_outlet_templates.all %}
|
|
||||||
<tr>
|
|
||||||
<td>{{ po.name }}</td>
|
|
||||||
<td></td>
|
|
||||||
</tr>
|
|
||||||
{% endfor %}
|
|
||||||
</table>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
29
netbox/templates/dcim/inc/devicetype_component_table.html
Normal file
29
netbox/templates/dcim/inc/devicetype_component_table.html
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
{% load render_table from django_tables2 %}
|
||||||
|
{% if perms.dcim.change_devicetype %}
|
||||||
|
<form method="post" action="{% url delete_url pk=devicetype.pk %}">
|
||||||
|
{% csrf_token %}
|
||||||
|
<div class="panel panel-default">
|
||||||
|
<div class="panel-heading">
|
||||||
|
<a href="{% url add_url pk=devicetype.pk %}" class="btn btn-primary btn-xs pull-right"><span class="glyphicon glyphicon-plus" aria-hidden="true"></span> Add {{ title }}</a>
|
||||||
|
<strong>{{ title }}</strong>
|
||||||
|
</div>
|
||||||
|
{% render_table table 'table.html' %}
|
||||||
|
{% if table.rows %}
|
||||||
|
<div class="panel-footer">
|
||||||
|
<button type="submit" class="btn btn-xs btn-danger">
|
||||||
|
<span class="glyphicon glyphicon-trash" aria-hidden="true"></span> Delete Selected
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
{% else %}
|
||||||
|
<div class="panel panel-default">
|
||||||
|
<div class="panel-heading">
|
||||||
|
<strong>{{ title }}</strong>
|
||||||
|
</div>
|
||||||
|
<table class="table table-hover panel-body">
|
||||||
|
{% render_table table table_template|default:'table.html' %}
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
Loading…
Reference in New Issue
Block a user