mirror of
https://github.com/netbox-community/netbox.git
synced 2025-07-15 11:42:52 -06:00
Added CableListView
This commit is contained in:
parent
f30367e094
commit
9985f2cb82
@ -4,7 +4,7 @@ from django_tables2.utils import Accessor
|
|||||||
from tenancy.tables import COL_TENANT
|
from tenancy.tables import COL_TENANT
|
||||||
from utilities.tables import BaseTable, BooleanColumn, ToggleColumn
|
from utilities.tables import BaseTable, BooleanColumn, ToggleColumn
|
||||||
from .models import (
|
from .models import (
|
||||||
ConsolePort, ConsolePortTemplate, ConsoleServerPort, ConsoleServerPortTemplate, Device, DeviceBay,
|
Cable, ConsolePort, ConsolePortTemplate, ConsoleServerPort, ConsoleServerPortTemplate, Device, DeviceBay,
|
||||||
DeviceBayTemplate, DeviceRole, DeviceType, FrontPanelPort, FrontPanelPortTemplate, Interface, InterfaceTemplate,
|
DeviceBayTemplate, DeviceRole, DeviceType, FrontPanelPort, FrontPanelPortTemplate, Interface, InterfaceTemplate,
|
||||||
InventoryItem, Manufacturer, Platform, PowerOutlet, PowerOutletTemplate, PowerPort, PowerPortTemplate, Rack,
|
InventoryItem, Manufacturer, Platform, PowerOutlet, PowerOutletTemplate, PowerPort, PowerPortTemplate, Rack,
|
||||||
RackGroup, RackReservation, RearPanelPort, RearPanelPortTemplate, Region, Site, VirtualChassis,
|
RackGroup, RackReservation, RearPanelPort, RearPanelPortTemplate, Region, Site, VirtualChassis,
|
||||||
@ -616,6 +616,42 @@ class DeviceBayTable(BaseTable):
|
|||||||
fields = ('name',)
|
fields = ('name',)
|
||||||
|
|
||||||
|
|
||||||
|
#
|
||||||
|
# Cables
|
||||||
|
#
|
||||||
|
|
||||||
|
class CableTable(BaseTable):
|
||||||
|
device_a = tables.LinkColumn(
|
||||||
|
viewname='dcim:device',
|
||||||
|
accessor=Accessor('endpoint_a.device'),
|
||||||
|
args=[Accessor('endpoint_a.device.pk')],
|
||||||
|
verbose_name='Device A'
|
||||||
|
)
|
||||||
|
termination_a = tables.Column(
|
||||||
|
accessor=Accessor('endpoint_a.name'),
|
||||||
|
verbose_name='Component'
|
||||||
|
)
|
||||||
|
device_b = tables.LinkColumn(
|
||||||
|
viewname='dcim:device',
|
||||||
|
accessor=Accessor('endpoint_b.device'),
|
||||||
|
args=[Accessor('endpoint_b.device.pk')],
|
||||||
|
verbose_name='Device B'
|
||||||
|
)
|
||||||
|
termination_b = tables.Column(
|
||||||
|
accessor=Accessor('endpoint_b.name'),
|
||||||
|
verbose_name='Component'
|
||||||
|
)
|
||||||
|
# django-tables2 adds CSS `class="label"` which causes rendering issues
|
||||||
|
_label = tables.Column(
|
||||||
|
accessor=Accessor('label'),
|
||||||
|
verbose_name='Label'
|
||||||
|
)
|
||||||
|
|
||||||
|
class Meta(BaseTable.Meta):
|
||||||
|
model = Cable
|
||||||
|
fields = ('device_a', 'termination_a', 'device_b', 'termination_b', 'status', '_label', 'color')
|
||||||
|
|
||||||
|
|
||||||
#
|
#
|
||||||
# Device connections
|
# Device connections
|
||||||
#
|
#
|
||||||
|
@ -162,7 +162,7 @@ urlpatterns = [
|
|||||||
url(r'^devices/(?P<pk>\d+)/console-ports/add/$', views.ConsolePortCreateView.as_view(), name='consoleport_add'),
|
url(r'^devices/(?P<pk>\d+)/console-ports/add/$', views.ConsolePortCreateView.as_view(), name='consoleport_add'),
|
||||||
url(r'^devices/(?P<pk>\d+)/console-ports/delete/$', views.ConsolePortBulkDeleteView.as_view(), name='consoleport_bulk_delete'),
|
url(r'^devices/(?P<pk>\d+)/console-ports/delete/$', views.ConsolePortBulkDeleteView.as_view(), name='consoleport_bulk_delete'),
|
||||||
# url(r'^console-ports/(?P<pk>\d+)/connect/$', views.ConsolePortConnectView.as_view(), name='consoleport_connect'),
|
# url(r'^console-ports/(?P<pk>\d+)/connect/$', views.ConsolePortConnectView.as_view(), name='consoleport_connect'),
|
||||||
url(r'^console-ports/(?P<endpoint_a_id>\d+)/connect/$', views.CableConnectView.as_view(), name='consoleport_connect', kwargs={'endpoint_a_type': ConsolePort}),
|
url(r'^console-ports/(?P<endpoint_a_id>\d+)/connect/$', views.CableCreateView.as_view(), name='consoleport_connect', kwargs={'endpoint_a_type': ConsolePort}),
|
||||||
url(r'^console-ports/(?P<pk>\d+)/disconnect/$', views.ConsolePortDisconnectView.as_view(), name='consoleport_disconnect'),
|
url(r'^console-ports/(?P<pk>\d+)/disconnect/$', views.ConsolePortDisconnectView.as_view(), name='consoleport_disconnect'),
|
||||||
url(r'^console-ports/(?P<pk>\d+)/edit/$', views.ConsolePortEditView.as_view(), name='consoleport_edit'),
|
url(r'^console-ports/(?P<pk>\d+)/edit/$', views.ConsolePortEditView.as_view(), name='consoleport_edit'),
|
||||||
url(r'^console-ports/(?P<pk>\d+)/delete/$', views.ConsolePortDeleteView.as_view(), name='consoleport_delete'),
|
url(r'^console-ports/(?P<pk>\d+)/delete/$', views.ConsolePortDeleteView.as_view(), name='consoleport_delete'),
|
||||||
@ -173,7 +173,7 @@ urlpatterns = [
|
|||||||
url(r'^devices/(?P<pk>\d+)/console-server-ports/disconnect/$', views.ConsoleServerPortBulkDisconnectView.as_view(), name='consoleserverport_bulk_disconnect'),
|
url(r'^devices/(?P<pk>\d+)/console-server-ports/disconnect/$', views.ConsoleServerPortBulkDisconnectView.as_view(), name='consoleserverport_bulk_disconnect'),
|
||||||
url(r'^devices/(?P<pk>\d+)/console-server-ports/delete/$', views.ConsoleServerPortBulkDeleteView.as_view(), name='consoleserverport_bulk_delete'),
|
url(r'^devices/(?P<pk>\d+)/console-server-ports/delete/$', views.ConsoleServerPortBulkDeleteView.as_view(), name='consoleserverport_bulk_delete'),
|
||||||
# url(r'^console-server-ports/(?P<pk>\d+)/connect/$', views.ConsoleServerPortConnectView.as_view(), name='consoleserverport_connect'),
|
# url(r'^console-server-ports/(?P<pk>\d+)/connect/$', views.ConsoleServerPortConnectView.as_view(), name='consoleserverport_connect'),
|
||||||
url(r'^console-server-ports/(?P<endpoint_a_id>\d+)/connect/$', views.CableConnectView.as_view(), name='consoleserverport_connect', kwargs={'endpoint_a_type': ConsoleServerPort}),
|
url(r'^console-server-ports/(?P<endpoint_a_id>\d+)/connect/$', views.CableCreateView.as_view(), name='consoleserverport_connect', kwargs={'endpoint_a_type': ConsoleServerPort}),
|
||||||
url(r'^console-server-ports/(?P<pk>\d+)/disconnect/$', views.ConsoleServerPortDisconnectView.as_view(), name='consoleserverport_disconnect'),
|
url(r'^console-server-ports/(?P<pk>\d+)/disconnect/$', views.ConsoleServerPortDisconnectView.as_view(), name='consoleserverport_disconnect'),
|
||||||
url(r'^console-server-ports/(?P<pk>\d+)/edit/$', views.ConsoleServerPortEditView.as_view(), name='consoleserverport_edit'),
|
url(r'^console-server-ports/(?P<pk>\d+)/edit/$', views.ConsoleServerPortEditView.as_view(), name='consoleserverport_edit'),
|
||||||
url(r'^console-server-ports/(?P<pk>\d+)/delete/$', views.ConsoleServerPortDeleteView.as_view(), name='consoleserverport_delete'),
|
url(r'^console-server-ports/(?P<pk>\d+)/delete/$', views.ConsoleServerPortDeleteView.as_view(), name='consoleserverport_delete'),
|
||||||
@ -184,7 +184,7 @@ urlpatterns = [
|
|||||||
url(r'^devices/(?P<pk>\d+)/power-ports/add/$', views.PowerPortCreateView.as_view(), name='powerport_add'),
|
url(r'^devices/(?P<pk>\d+)/power-ports/add/$', views.PowerPortCreateView.as_view(), name='powerport_add'),
|
||||||
url(r'^devices/(?P<pk>\d+)/power-ports/delete/$', views.PowerPortBulkDeleteView.as_view(), name='powerport_bulk_delete'),
|
url(r'^devices/(?P<pk>\d+)/power-ports/delete/$', views.PowerPortBulkDeleteView.as_view(), name='powerport_bulk_delete'),
|
||||||
# url(r'^power-ports/(?P<pk>\d+)/connect/$', views.PowerPortConnectView.as_view(), name='powerport_connect'),
|
# url(r'^power-ports/(?P<pk>\d+)/connect/$', views.PowerPortConnectView.as_view(), name='powerport_connect'),
|
||||||
url(r'^power-ports/(?P<endpoint_a_id>\d+)/connect/$', views.CableConnectView.as_view(), name='powerport_connect', kwargs={'endpoint_a_type': PowerPort}),
|
url(r'^power-ports/(?P<endpoint_a_id>\d+)/connect/$', views.CableCreateView.as_view(), name='powerport_connect', kwargs={'endpoint_a_type': PowerPort}),
|
||||||
url(r'^power-ports/(?P<pk>\d+)/disconnect/$', views.PowerPortDisconnectView.as_view(), name='powerport_disconnect'),
|
url(r'^power-ports/(?P<pk>\d+)/disconnect/$', views.PowerPortDisconnectView.as_view(), name='powerport_disconnect'),
|
||||||
url(r'^power-ports/(?P<pk>\d+)/edit/$', views.PowerPortEditView.as_view(), name='powerport_edit'),
|
url(r'^power-ports/(?P<pk>\d+)/edit/$', views.PowerPortEditView.as_view(), name='powerport_edit'),
|
||||||
url(r'^power-ports/(?P<pk>\d+)/delete/$', views.PowerPortDeleteView.as_view(), name='powerport_delete'),
|
url(r'^power-ports/(?P<pk>\d+)/delete/$', views.PowerPortDeleteView.as_view(), name='powerport_delete'),
|
||||||
@ -195,7 +195,7 @@ urlpatterns = [
|
|||||||
url(r'^devices/(?P<pk>\d+)/power-outlets/disconnect/$', views.PowerOutletBulkDisconnectView.as_view(), name='poweroutlet_bulk_disconnect'),
|
url(r'^devices/(?P<pk>\d+)/power-outlets/disconnect/$', views.PowerOutletBulkDisconnectView.as_view(), name='poweroutlet_bulk_disconnect'),
|
||||||
url(r'^devices/(?P<pk>\d+)/power-outlets/delete/$', views.PowerOutletBulkDeleteView.as_view(), name='poweroutlet_bulk_delete'),
|
url(r'^devices/(?P<pk>\d+)/power-outlets/delete/$', views.PowerOutletBulkDeleteView.as_view(), name='poweroutlet_bulk_delete'),
|
||||||
# url(r'^power-outlets/(?P<pk>\d+)/connect/$', views.PowerOutletConnectView.as_view(), name='poweroutlet_connect'),
|
# url(r'^power-outlets/(?P<pk>\d+)/connect/$', views.PowerOutletConnectView.as_view(), name='poweroutlet_connect'),
|
||||||
url(r'^power-outlets/(?P<endpoint_a_id>\d+)/connect/$', views.CableConnectView.as_view(), name='poweroutlet_connect', kwargs={'endpoint_a_type': PowerOutlet}),
|
url(r'^power-outlets/(?P<endpoint_a_id>\d+)/connect/$', views.CableCreateView.as_view(), name='poweroutlet_connect', kwargs={'endpoint_a_type': PowerOutlet}),
|
||||||
url(r'^power-outlets/(?P<pk>\d+)/disconnect/$', views.PowerOutletDisconnectView.as_view(), name='poweroutlet_disconnect'),
|
url(r'^power-outlets/(?P<pk>\d+)/disconnect/$', views.PowerOutletDisconnectView.as_view(), name='poweroutlet_disconnect'),
|
||||||
url(r'^power-outlets/(?P<pk>\d+)/edit/$', views.PowerOutletEditView.as_view(), name='poweroutlet_edit'),
|
url(r'^power-outlets/(?P<pk>\d+)/edit/$', views.PowerOutletEditView.as_view(), name='poweroutlet_edit'),
|
||||||
url(r'^power-outlets/(?P<pk>\d+)/delete/$', views.PowerOutletDeleteView.as_view(), name='poweroutlet_delete'),
|
url(r'^power-outlets/(?P<pk>\d+)/delete/$', views.PowerOutletDeleteView.as_view(), name='poweroutlet_delete'),
|
||||||
@ -207,9 +207,7 @@ urlpatterns = [
|
|||||||
url(r'^devices/(?P<pk>\d+)/interfaces/edit/$', views.InterfaceBulkEditView.as_view(), name='interface_bulk_edit'),
|
url(r'^devices/(?P<pk>\d+)/interfaces/edit/$', views.InterfaceBulkEditView.as_view(), name='interface_bulk_edit'),
|
||||||
url(r'^devices/(?P<pk>\d+)/interfaces/disconnect/$', views.InterfaceBulkDisconnectView.as_view(), name='interface_bulk_disconnect'),
|
url(r'^devices/(?P<pk>\d+)/interfaces/disconnect/$', views.InterfaceBulkDisconnectView.as_view(), name='interface_bulk_disconnect'),
|
||||||
url(r'^devices/(?P<pk>\d+)/interfaces/delete/$', views.InterfaceBulkDeleteView.as_view(), name='interface_bulk_delete'),
|
url(r'^devices/(?P<pk>\d+)/interfaces/delete/$', views.InterfaceBulkDeleteView.as_view(), name='interface_bulk_delete'),
|
||||||
# url(r'^devices/(?P<pk>\d+)/interface-connections/add/$', views.InterfaceConnectionAddView.as_view(), name='interfaceconnection_add'),
|
url(r'^interfaces/(?P<endpoint_a_id>\d+)/connect/$', views.CableCreateView.as_view(), name='interface_connect', kwargs={'endpoint_a_type': Interface}),
|
||||||
url(r'^interfaces/(?P<endpoint_a_id>\d+)/connect/$', views.CableConnectView.as_view(), name='interface_connect', kwargs={'endpoint_a_type': Interface}),
|
|
||||||
# url(r'^interface-connections/(?P<pk>\d+)/delete/$', views.InterfaceConnectionDeleteView.as_view(), name='interfaceconnection_delete'),
|
|
||||||
url(r'^interfaces/(?P<pk>\d+)/$', views.InterfaceView.as_view(), name='interface'),
|
url(r'^interfaces/(?P<pk>\d+)/$', views.InterfaceView.as_view(), name='interface'),
|
||||||
url(r'^interfaces/(?P<pk>\d+)/edit/$', views.InterfaceEditView.as_view(), name='interface_edit'),
|
url(r'^interfaces/(?P<pk>\d+)/edit/$', views.InterfaceEditView.as_view(), name='interface_edit'),
|
||||||
url(r'^interfaces/(?P<pk>\d+)/assign-vlans/$', views.InterfaceAssignVLANsView.as_view(), name='interface_assign_vlans'),
|
url(r'^interfaces/(?P<pk>\d+)/assign-vlans/$', views.InterfaceAssignVLANsView.as_view(), name='interface_assign_vlans'),
|
||||||
@ -252,6 +250,10 @@ urlpatterns = [
|
|||||||
url(r'^inventory-items/(?P<pk>\d+)/delete/$', views.InventoryItemDeleteView.as_view(), name='inventoryitem_delete'),
|
url(r'^inventory-items/(?P<pk>\d+)/delete/$', views.InventoryItemDeleteView.as_view(), name='inventoryitem_delete'),
|
||||||
url(r'^devices/(?P<device>\d+)/inventory-items/add/$', views.InventoryItemEditView.as_view(), name='inventoryitem_add'),
|
url(r'^devices/(?P<device>\d+)/inventory-items/add/$', views.InventoryItemEditView.as_view(), name='inventoryitem_add'),
|
||||||
|
|
||||||
|
# Cables
|
||||||
|
url(r'^cables/$', views.CableListView.as_view(), name='cable_list'),
|
||||||
|
url(r'^cables/(?P<pk>\d+)/delete/$', views.CableDeleteView.as_view(), name='cable_delete'),
|
||||||
|
|
||||||
# Console/power/interface connections
|
# Console/power/interface connections
|
||||||
url(r'^console-connections/$', views.ConsoleConnectionsListView.as_view(), name='console_connections_list'),
|
url(r'^console-connections/$', views.ConsoleConnectionsListView.as_view(), name='console_connections_list'),
|
||||||
# url(r'^console-connections/import/$', views.ConsoleConnectionsBulkImportView.as_view(), name='console_connections_import'),
|
# url(r'^console-connections/import/$', views.ConsoleConnectionsBulkImportView.as_view(), name='console_connections_import'),
|
||||||
|
@ -1,18 +1,14 @@
|
|||||||
from operator import attrgetter
|
from operator import attrgetter
|
||||||
|
|
||||||
from django.apps import apps
|
|
||||||
from django.contrib import messages
|
from django.contrib import messages
|
||||||
from django.contrib.auth.mixins import PermissionRequiredMixin
|
from django.contrib.auth.mixins import PermissionRequiredMixin
|
||||||
from django.core.exceptions import ObjectDoesNotExist
|
|
||||||
from django.core.paginator import EmptyPage, PageNotAnInteger
|
from django.core.paginator import EmptyPage, PageNotAnInteger
|
||||||
from django.db import transaction
|
from django.db import transaction
|
||||||
from django.db.models import Count, F, Q
|
from django.db.models import Count, F
|
||||||
from django.forms import modelformset_factory
|
from django.forms import modelformset_factory
|
||||||
from django.http import Http404, HttpResponseRedirect
|
|
||||||
from django.shortcuts import get_object_or_404, redirect, render
|
from django.shortcuts import get_object_or_404, redirect, render
|
||||||
from django.urls import reverse
|
from django.urls import reverse
|
||||||
from django.utils.html import escape
|
from django.utils.html import escape
|
||||||
from django.utils.http import urlencode
|
|
||||||
from django.utils.safestring import mark_safe
|
from django.utils.safestring import mark_safe
|
||||||
from django.views.generic import View
|
from django.views.generic import View
|
||||||
from natsort import natsorted
|
from natsort import natsorted
|
||||||
@ -2013,6 +2009,43 @@ class DeviceBulkAddDeviceBayView(PermissionRequiredMixin, BulkComponentCreateVie
|
|||||||
default_return_url = 'dcim:device_list'
|
default_return_url = 'dcim:device_list'
|
||||||
|
|
||||||
|
|
||||||
|
#
|
||||||
|
# Cables
|
||||||
|
#
|
||||||
|
|
||||||
|
class CableListView(ObjectListView):
|
||||||
|
queryset = Cable.objects.prefetch_related(
|
||||||
|
'endpoint_a__device', 'endpoint_b__device'
|
||||||
|
)
|
||||||
|
# filter = filters.CableFilter
|
||||||
|
# filter_form = forms.CableFilterForm
|
||||||
|
table = tables.CableTable
|
||||||
|
template_name = 'dcim/cable_list.html'
|
||||||
|
|
||||||
|
|
||||||
|
class CableCreateView(PermissionRequiredMixin, ObjectEditView):
|
||||||
|
permission_required = 'dcim.add_cable'
|
||||||
|
model = Cable
|
||||||
|
model_form = forms.CableForm
|
||||||
|
template_name = 'dcim/cable_connect.html'
|
||||||
|
|
||||||
|
def alter_obj(self, obj, request, url_args, url_kwargs):
|
||||||
|
|
||||||
|
# Retrieve endpoint A based on the given type and PK
|
||||||
|
endpoint_a_type = url_kwargs.get('endpoint_a_type')
|
||||||
|
endpoint_a_id = url_kwargs.get('endpoint_a_id')
|
||||||
|
obj.endpoint_a = endpoint_a_type.objects.get(pk=endpoint_a_id)
|
||||||
|
|
||||||
|
return obj
|
||||||
|
|
||||||
|
|
||||||
|
class CableDeleteView(PermissionRequiredMixin, ObjectDeleteView):
|
||||||
|
permission_required = 'dcim.delete_cable'
|
||||||
|
model = Cable
|
||||||
|
default_return_url = 'dcim:cable_list'
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#
|
#
|
||||||
# Connections
|
# Connections
|
||||||
#
|
#
|
||||||
@ -2058,22 +2091,6 @@ class InterfaceConnectionsListView(ObjectListView):
|
|||||||
template_name = 'dcim/interface_connections_list.html'
|
template_name = 'dcim/interface_connections_list.html'
|
||||||
|
|
||||||
|
|
||||||
class CableConnectView(PermissionRequiredMixin, ObjectEditView):
|
|
||||||
permission_required = 'dcim.add_cable'
|
|
||||||
model = Cable
|
|
||||||
model_form = forms.CableForm
|
|
||||||
template_name = 'dcim/cable_connect.html'
|
|
||||||
|
|
||||||
def alter_obj(self, obj, request, url_args, url_kwargs):
|
|
||||||
|
|
||||||
# Retrieve endpoint A based on the given type and PK
|
|
||||||
endpoint_a_type = url_kwargs.get('endpoint_a_type')
|
|
||||||
endpoint_a_id = url_kwargs.get('endpoint_a_id')
|
|
||||||
obj.endpoint_a = endpoint_a_type.objects.get(pk=endpoint_a_id)
|
|
||||||
|
|
||||||
return obj
|
|
||||||
|
|
||||||
|
|
||||||
#
|
#
|
||||||
# Inventory items
|
# Inventory items
|
||||||
#
|
#
|
||||||
|
17
netbox/templates/dcim/cable_list.html
Normal file
17
netbox/templates/dcim/cable_list.html
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
{% extends '_base.html' %}
|
||||||
|
{% load buttons %}
|
||||||
|
|
||||||
|
{% block content %}
|
||||||
|
<div class="pull-right">
|
||||||
|
{% export_button content_type %}
|
||||||
|
</div>
|
||||||
|
<h1>{% block title %}Cables{% endblock %}</h1>
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-md-9">
|
||||||
|
{% include 'responsive_table.html' %}
|
||||||
|
</div>
|
||||||
|
<div class="col-md-3">
|
||||||
|
{% include 'inc/search_panel.html' %}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{% endblock %}
|
@ -113,7 +113,7 @@
|
|||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</li>
|
</li>
|
||||||
<li class="dropdown{% if request.path|contains:'/dcim/device,/dcim/virtual-chassis,/dcim/manufacturers/,/dcim/platforms/,-connections/,/dcim/inventory-items/' %} active{% endif %}">
|
<li class="dropdown{% if request.path|contains:'/dcim/device,/dcim/virtual-chassis,/dcim/manufacturers/,/dcim/platforms/,/dcim/cable,-connections/,/dcim/inventory-items/' %} active{% endif %}">
|
||||||
<a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false">Devices <span class="caret"></span></a>
|
<a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false">Devices <span class="caret"></span></a>
|
||||||
<ul class="dropdown-menu">
|
<ul class="dropdown-menu">
|
||||||
<li class="dropdown-header">Devices</li>
|
<li class="dropdown-header">Devices</li>
|
||||||
@ -179,6 +179,9 @@
|
|||||||
</li>
|
</li>
|
||||||
<li class="divider"></li>
|
<li class="divider"></li>
|
||||||
<li class="dropdown-header">Connections</li>
|
<li class="dropdown-header">Connections</li>
|
||||||
|
<li>
|
||||||
|
<a href="{% url 'dcim:cable_list' %}">Cables</a>
|
||||||
|
</li>
|
||||||
<li>
|
<li>
|
||||||
<a href="{% url 'dcim:console_connections_list' %}">Console Connections</a>
|
<a href="{% url 'dcim:console_connections_list' %}">Console Connections</a>
|
||||||
</li>
|
</li>
|
||||||
|
Loading…
Reference in New Issue
Block a user