From 77f0eeb7bf697ab3bf29ab2e22186b69c281ed62 Mon Sep 17 00:00:00 2001 From: Jeremy Stretch Date: Tue, 3 Jun 2025 10:34:39 -0400 Subject: [PATCH] Fixes #19587: Occupied filter should match on interfaces terminating a wireless link (#19631) --- netbox/dcim/filtersets.py | 15 +++++++++++++++ netbox/dcim/tests/test_filtersets.py | 13 ++++++++----- 2 files changed, 23 insertions(+), 5 deletions(-) diff --git a/netbox/dcim/filtersets.py b/netbox/dcim/filtersets.py index a31cf136d..7f1493557 100644 --- a/netbox/dcim/filtersets.py +++ b/netbox/dcim/filtersets.py @@ -2012,6 +2012,21 @@ class InterfaceFilterSet( 'wireless': queryset.filter(type__in=WIRELESS_IFACE_TYPES), }.get(value, queryset.none()) + # Override the method on CabledObjectFilterSet to also check for wireless links + def filter_occupied(self, queryset, name, value): + if value: + return queryset.filter( + Q(cable__isnull=False) | + Q(wireless_link__isnull=False) | + Q(mark_connected=True) + ) + else: + return queryset.filter( + cable__isnull=True, + wireless_link__isnull=True, + mark_connected=False + ) + class FrontPortFilterSet( ModularDeviceComponentFilterSet, diff --git a/netbox/dcim/tests/test_filtersets.py b/netbox/dcim/tests/test_filtersets.py index ba8d4203d..2ae178653 100644 --- a/netbox/dcim/tests/test_filtersets.py +++ b/netbox/dcim/tests/test_filtersets.py @@ -12,6 +12,7 @@ from users.models import User from utilities.testing import ChangeLoggedFilterSetTests, create_test_device, create_test_virtualmachine from virtualization.models import Cluster, ClusterType, ClusterGroup, VMInterface, VirtualMachine from wireless.choices import WirelessChannelChoices, WirelessRoleChoices +from wireless.models import WirelessLink class DeviceComponentFilterSetTests: @@ -4496,7 +4497,9 @@ class InterfaceTestCase(TestCase, DeviceComponentFilterSetTests, ChangeLoggedFil # Cables Cable(a_terminations=[interfaces[0]], b_terminations=[interfaces[5]]).save() Cable(a_terminations=[interfaces[1]], b_terminations=[interfaces[6]]).save() - # Third pair is not connected + + # Wireless links + WirelessLink(interface_a=interfaces[7], interface_b=interfaces[8]).save() def test_name(self): params = {'name': ['Interface 1', 'Interface 2']} @@ -4684,15 +4687,15 @@ class InterfaceTestCase(TestCase, DeviceComponentFilterSetTests, ChangeLoggedFil def test_occupied(self): params = {'occupied': True} - self.assertEqual(self.filterset(params, self.queryset).qs.count(), 4) + self.assertEqual(self.filterset(params, self.queryset).qs.count(), 6) params = {'occupied': False} - self.assertEqual(self.filterset(params, self.queryset).qs.count(), 5) + self.assertEqual(self.filterset(params, self.queryset).qs.count(), 3) def test_connected(self): params = {'connected': True} - self.assertEqual(self.filterset(params, self.queryset).qs.count(), 4) + self.assertEqual(self.filterset(params, self.queryset).qs.count(), 6) params = {'connected': False} - self.assertEqual(self.filterset(params, self.queryset).qs.count(), 5) + self.assertEqual(self.filterset(params, self.queryset).qs.count(), 3) def test_kind(self): params = {'kind': 'physical'}