From 581560fa8aedc89e8ad19a017cf2683d0301dab8 Mon Sep 17 00:00:00 2001 From: Arthur Date: Mon, 20 May 2024 13:43:49 -0700 Subject: [PATCH 1/3] 14948 add has_virtual_device_cnotexts filter to device --- netbox/dcim/filtersets.py | 10 ++++++++++ netbox/dcim/forms/filtersets.py | 8 ++++++++ 2 files changed, 18 insertions(+) diff --git a/netbox/dcim/filtersets.py b/netbox/dcim/filtersets.py index ad1e29f2654..c1222f63fa6 100644 --- a/netbox/dcim/filtersets.py +++ b/netbox/dcim/filtersets.py @@ -1100,6 +1100,10 @@ class DeviceFilterSet( queryset=IPAddress.objects.all(), label=_('OOB IP (ID)'), ) + has_virtual_device_contexts = django_filters.BooleanFilter( + method='_has_virtual_device_contexts', + label=_('Has virtual device contexts'), + ) class Meta: model = Device @@ -1176,6 +1180,12 @@ def _module_bays(self, queryset, name, value): def _device_bays(self, queryset, name, value): return queryset.exclude(devicebays__isnull=value) + def _has_virtual_device_contexts(self, queryset, name, value): + params = Q(vdcs__isnull=False) + if value: + return queryset.filter(params).distinct() + return queryset.exclude(params) + class VirtualDeviceContextFilterSet(NetBoxModelFilterSet, TenancyFilterSet, PrimaryIPFilterSet): device_id = django_filters.ModelMultipleChoiceFilter( diff --git a/netbox/dcim/forms/filtersets.py b/netbox/dcim/forms/filtersets.py index 21854b53fef..6aea4f26e25 100644 --- a/netbox/dcim/forms/filtersets.py +++ b/netbox/dcim/forms/filtersets.py @@ -657,6 +657,7 @@ class DeviceFilterForm( ), FieldSet( 'has_primary_ip', 'has_oob_ip', 'virtual_chassis_member', 'config_template_id', 'local_context_data', + 'has_virtual_device_contexts', name=_('Miscellaneous') ) ) @@ -813,6 +814,13 @@ class DeviceFilterForm( choices=BOOLEAN_WITH_BLANK_CHOICES ) ) + has_virtual_device_contexts = forms.NullBooleanField( + required=False, + label=_('Has virtual device contexts'), + widget=forms.Select( + choices=BOOLEAN_WITH_BLANK_CHOICES + ) + ) tag = TagFilterField(model) From ecb02ec939472735cfb8cd6bd79c88fb1a22fdba Mon Sep 17 00:00:00 2001 From: Arthur Date: Tue, 21 May 2024 12:00:31 -0700 Subject: [PATCH 2/3] 14948 make singular --- netbox/dcim/filtersets.py | 8 ++++---- netbox/dcim/forms/filtersets.py | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/netbox/dcim/filtersets.py b/netbox/dcim/filtersets.py index c1222f63fa6..2fb1e9949c9 100644 --- a/netbox/dcim/filtersets.py +++ b/netbox/dcim/filtersets.py @@ -1100,9 +1100,9 @@ class DeviceFilterSet( queryset=IPAddress.objects.all(), label=_('OOB IP (ID)'), ) - has_virtual_device_contexts = django_filters.BooleanFilter( - method='_has_virtual_device_contexts', - label=_('Has virtual device contexts'), + has_virtual_device_context = django_filters.BooleanFilter( + method='_has_virtual_device_context', + label=_('Has virtual device context'), ) class Meta: @@ -1180,7 +1180,7 @@ def _module_bays(self, queryset, name, value): def _device_bays(self, queryset, name, value): return queryset.exclude(devicebays__isnull=value) - def _has_virtual_device_contexts(self, queryset, name, value): + def _has_virtual_device_context(self, queryset, name, value): params = Q(vdcs__isnull=False) if value: return queryset.filter(params).distinct() diff --git a/netbox/dcim/forms/filtersets.py b/netbox/dcim/forms/filtersets.py index 6aea4f26e25..0a28a4ec445 100644 --- a/netbox/dcim/forms/filtersets.py +++ b/netbox/dcim/forms/filtersets.py @@ -657,7 +657,7 @@ class DeviceFilterForm( ), FieldSet( 'has_primary_ip', 'has_oob_ip', 'virtual_chassis_member', 'config_template_id', 'local_context_data', - 'has_virtual_device_contexts', + 'has_virtual_device_context', name=_('Miscellaneous') ) ) @@ -814,7 +814,7 @@ class DeviceFilterForm( choices=BOOLEAN_WITH_BLANK_CHOICES ) ) - has_virtual_device_contexts = forms.NullBooleanField( + has_virtual_device_context = forms.NullBooleanField( required=False, label=_('Has virtual device contexts'), widget=forms.Select( From 08646d8cc006e78fe593f469fc9e23a9e84804a6 Mon Sep 17 00:00:00 2001 From: Arthur Date: Wed, 22 May 2024 07:32:25 -0700 Subject: [PATCH 3/3] 14948 add test --- netbox/dcim/tests/test_filtersets.py | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/netbox/dcim/tests/test_filtersets.py b/netbox/dcim/tests/test_filtersets.py index 96ea020b318..0a22f5a824b 100644 --- a/netbox/dcim/tests/test_filtersets.py +++ b/netbox/dcim/tests/test_filtersets.py @@ -2103,6 +2103,9 @@ def setUpTestData(cls): Device.objects.filter(pk=devices[0].pk).update(virtual_chassis=virtual_chassis, vc_position=1, vc_priority=1) Device.objects.filter(pk=devices[1].pk).update(virtual_chassis=virtual_chassis, vc_position=2, vc_priority=2) + # VirtualDeviceContext assignment for filtering + VirtualDeviceContext.objects.create(device=devices[0], name="VDC 1", identifier=1, status='active') + def test_q(self): params = {'q': 'foobar1'} self.assertEqual(self.filterset(params, self.queryset).qs.count(), 1) @@ -2336,6 +2339,12 @@ def test_tenant_group(self): params = {'tenant_group': [tenant_groups[0].slug, tenant_groups[1].slug]} self.assertEqual(self.filterset(params, self.queryset).qs.count(), 2) + def test_has_virtual_device_context(self): + params = {'has_virtual_device_context': 'true'} + self.assertEqual(self.filterset(params, self.queryset).qs.count(), 1) + params = {'has_virtual_device_context': 'false'} + self.assertEqual(self.filterset(params, self.queryset).qs.count(), 2) + class ModuleTestCase(TestCase, ChangeLoggedFilterSetTests): queryset = Module.objects.all()