diff --git a/netbox/dcim/models/device_components.py b/netbox/dcim/models/device_components.py index 12bb224fd..56e8f6fc4 100644 --- a/netbox/dcim/models/device_components.py +++ b/netbox/dcim/models/device_components.py @@ -252,15 +252,19 @@ class CableTermination(models.Model): return endpoints -class PathEndpoint: +class PathEndpoint(models.Model): + """ + Any object which may serve as either endpoint of a CablePath. + """ + paths = GenericRelation( + to='dcim.CablePath', + content_type_field='origin_type', + object_id_field='origin_id', + related_query_name='%(class)s' + ) - def get_connections(self): - from dcim.models import CablePath - return CablePath.objects.filter( - origin_type=ContentType.objects.get_for_model(self), - origin_id=self.pk, - destination_id__isnull=False - ) + class Meta: + abstract = True # diff --git a/netbox/dcim/views.py b/netbox/dcim/views.py index ce204bee0..58be5d213 100644 --- a/netbox/dcim/views.py +++ b/netbox/dcim/views.py @@ -32,7 +32,7 @@ from . import filters, forms, tables from .choices import DeviceFaceChoices from .constants import NONCONNECTABLE_IFACE_TYPES from .models import ( - Cable, ConsolePort, ConsolePortTemplate, ConsoleServerPort, ConsoleServerPortTemplate, Device, DeviceBay, + Cable, CablePath, ConsolePort, ConsolePortTemplate, ConsoleServerPort, ConsoleServerPortTemplate, Device, DeviceBay, DeviceBayTemplate, DeviceRole, DeviceType, FrontPort, FrontPortTemplate, Interface, InterfaceTemplate, InventoryItem, Manufacturer, Platform, PowerFeed, PowerOutlet, PowerOutletTemplate, PowerPanel, PowerPort, PowerPortTemplate, Rack, RackGroup, RackReservation, RackRole, RearPort, RearPortTemplate, Region, Site, @@ -1018,32 +1018,36 @@ class DeviceView(ObjectView): # Console ports consoleports = ConsolePort.objects.restrict(request.user, 'view').filter(device=device).prefetch_related( - 'connected_endpoint__device', 'cable', + Prefetch('paths', queryset=CablePath.objects.filter(destination_id__isnull=False)), + 'cable', ) # Console server ports consoleserverports = ConsoleServerPort.objects.restrict(request.user, 'view').filter( device=device ).prefetch_related( - 'connected_endpoint__device', 'cable', + Prefetch('paths', queryset=CablePath.objects.filter(destination_id__isnull=False)), + 'cable', ) # Power ports powerports = PowerPort.objects.restrict(request.user, 'view').filter(device=device).prefetch_related( - '_connected_poweroutlet__device', 'cable', + Prefetch('paths', queryset=CablePath.objects.filter(destination_id__isnull=False)), + 'cable', ) # Power outlets poweroutlets = PowerOutlet.objects.restrict(request.user, 'view').filter(device=device).prefetch_related( - 'connected_endpoint__device', 'cable', 'power_port', + Prefetch('paths', queryset=CablePath.objects.filter(destination_id__isnull=False)), + 'cable', 'power_port', ) # Interfaces interfaces = device.vc_interfaces.restrict(request.user, 'view').prefetch_related( + Prefetch('paths', queryset=CablePath.objects.filter(destination_id__isnull=False)), Prefetch('ip_addresses', queryset=IPAddress.objects.restrict(request.user)), Prefetch('member_interfaces', queryset=Interface.objects.restrict(request.user)), - 'lag', '_connected_interface__device', '_connected_circuittermination__circuit', 'cable', - 'cable__termination_a', 'cable__termination_b', 'tags' + 'lag', 'cable', 'tags', ) # Front ports diff --git a/netbox/templates/dcim/inc/consoleport.html b/netbox/templates/dcim/inc/consoleport.html index 6fa5e8b91..dc0ff384c 100644 --- a/netbox/templates/dcim/inc/consoleport.html +++ b/netbox/templates/dcim/inc/consoleport.html @@ -36,18 +36,7 @@ {# Connection #} - {% if cp.connected_endpoint %} -