Просмотр исходного кода

Closes #3023: Add support for filtering cables by connected device

Jeremy Stretch 6 лет назад
Родитель
Сommit
6d778f686d
3 измененных файлов с 36 добавлено и 0 удалено
  1. 1 0
      CHANGELOG.md
  2. 20 0
      netbox/dcim/filters.py
  3. 15 0
      netbox/dcim/models.py

+ 1 - 0
CHANGELOG.md

@@ -3,6 +3,7 @@
 ## Enhancements
 
 * [#2986](https://github.com/digitalocean/netbox/issues/2986) - Improve natural ordering of device components
+* [#3023](https://github.com/digitalocean/netbox/issues/3023) - Add support for filtering cables by connected device
 * [#3070](https://github.com/digitalocean/netbox/issues/3070) - Add decommissioning status for devices
 
 ## Bug Fixes

+ 20 - 0
netbox/dcim/filters.py

@@ -1,5 +1,7 @@
 import django_filters
 from django.contrib.auth.models import User
+from django.contrib.contenttypes.models import ContentType
+from django.core.exceptions import ObjectDoesNotExist
 from django.db.models import Q
 from netaddr import EUI
 from netaddr.core import AddrFormatError
@@ -967,6 +969,14 @@ class CableFilter(django_filters.FilterSet):
     color = django_filters.MultipleChoiceFilter(
         choices=COLOR_CHOICES
     )
+    device = django_filters.CharFilter(
+        method='filter_connected_device',
+        field_name='name'
+    )
+    device_id = django_filters.CharFilter(
+        method='filter_connected_device',
+        field_name='pk'
+    )
 
     class Meta:
         model = Cable
@@ -977,6 +987,16 @@ class CableFilter(django_filters.FilterSet):
             return queryset
         return queryset.filter(label__icontains=value)
 
+    def filter_connected_device(self, queryset, name, value):
+        if not value.strip():
+            return queryset
+        try:
+            device = Device.objects.get(**{name: value})
+        except ObjectDoesNotExist:
+            return queryset.none()
+        cable_pks = device.get_cables(pk_list=True)
+        return queryset.filter(pk__in=cable_pks)
+
 
 class ConsoleConnectionFilter(django_filters.FilterSet):
     site = django_filters.CharFilter(

+ 15 - 0
netbox/dcim/models.py

@@ -1704,6 +1704,21 @@ class Device(ChangeLoggedModel, ConfigContextModel, CustomFieldModel):
             filter |= Q(device__virtual_chassis=self.virtual_chassis, mgmt_only=False)
         return Interface.objects.filter(filter)
 
+    def get_cables(self, pk_list=False):
+        """
+        Return a QuerySet or PK list matching all Cables connected to a component of this Device.
+        """
+        cable_pks = []
+        for component_model in [
+            ConsolePort, ConsoleServerPort, PowerPort, PowerOutlet, Interface, FrontPort, RearPort
+        ]:
+            cable_pks += component_model.objects.filter(
+                device=self, cable__isnull=False
+            ).values_list('cable', flat=True)
+        if pk_list:
+            return cable_pks
+        return Cable.objects.filter(pk__in=cable_pks)
+
     def get_children(self):
         """
         Return the set of child Devices installed in DeviceBays within this Device.