Skip to content

Commit a01d85d

Browse files
committed
Fixes: #17663 - Only remove extraneous attributes from extra if changing to a BooleanFilter (#17670)
* Only remove extraneous attributes from extra if changing to a BooleanField * Add tests for MultipleChoiceField icontains and negation * Use enum in test consistently * Reorganize tests * Add __empty test to base filter lookup tests * Fix test name * Change var name for clarity
1 parent edaf4e3 commit a01d85d

File tree

2 files changed

+25
-8
lines changed

2 files changed

+25
-8
lines changed

netbox/netbox/filtersets.py

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -180,9 +180,11 @@ def get_additional_lookups(cls, existing_filter_name, existing_filter):
180180
# create the new filter with the same type because there is no guarantee the defined type
181181
# is the same as the default type for the field
182182
resolve_field(field, lookup_expr) # Will raise FieldLookupError if the lookup is invalid
183-
for field_to_remove in ('choices', 'null_value'):
184-
existing_filter_extra.pop(field_to_remove, None)
185-
filter_cls = django_filters.BooleanFilter if lookup_expr == 'empty' else type(existing_filter)
183+
filter_cls = type(existing_filter)
184+
if lookup_expr == 'empty':
185+
filter_cls = django_filters.BooleanFilter
186+
for param_to_remove in ('choices', 'null_value'):
187+
existing_filter_extra.pop(param_to_remove, None)
186188
new_filter = filter_cls(
187189
field_name=field_name,
188190
lookup_expr=lookup_expr,

netbox/utilities/tests/test_filters.py

Lines changed: 20 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77

88
from dcim.choices import *
99
from dcim.fields import MACAddressField
10-
from dcim.filtersets import DeviceFilterSet, SiteFilterSet
10+
from dcim.filtersets import DeviceFilterSet, SiteFilterSet, InterfaceFilterSet
1111
from dcim.models import (
1212
Device, DeviceRole, DeviceType, Interface, Manufacturer, Platform, Rack, Region, Site
1313
)
@@ -16,6 +16,7 @@
1616
from ipam.filtersets import ASNFilterSet
1717
from ipam.models import RIR, ASN
1818
from netbox.filtersets import BaseFilterSet
19+
from wireless.choices import WirelessRoleChoices
1920
from utilities.filters import (
2021
MultiValueCharFilter, MultiValueDateFilter, MultiValueDateTimeFilter, MultiValueMACAddressFilter,
2122
MultiValueNumberFilter, MultiValueTimeFilter, TreeNodeMultipleChoiceFilter,
@@ -408,9 +409,9 @@ def setUpTestData(cls):
408409
region.save()
409410

410411
sites = (
411-
Site(name='Site 1', slug='abc-site-1', region=regions[0]),
412-
Site(name='Site 2', slug='def-site-2', region=regions[1]),
413-
Site(name='Site 3', slug='ghi-site-3', region=regions[2]),
412+
Site(name='Site 1', slug='abc-site-1', region=regions[0], status=SiteStatusChoices.STATUS_ACTIVE),
413+
Site(name='Site 2', slug='def-site-2', region=regions[1], status=SiteStatusChoices.STATUS_ACTIVE),
414+
Site(name='Site 3', slug='ghi-site-3', region=regions[2], status=SiteStatusChoices.STATUS_PLANNED),
414415
)
415416
Site.objects.bulk_create(sites)
416417

@@ -438,14 +439,22 @@ def setUpTestData(cls):
438439
Interface(device=devices[1], name='Interface 3', mac_address='00-00-00-00-00-02'),
439440
Interface(device=devices[1], name='Interface 4', mac_address='bb-00-00-00-00-02'),
440441
Interface(device=devices[2], name='Interface 5', mac_address='00-00-00-00-00-03'),
441-
Interface(device=devices[2], name='Interface 6', mac_address='cc-00-00-00-00-03'),
442+
Interface(device=devices[2], name='Interface 6', mac_address='cc-00-00-00-00-03', rf_role=WirelessRoleChoices.ROLE_AP),
442443
)
443444
Interface.objects.bulk_create(interfaces)
444445

445446
def test_site_name_negation(self):
446447
params = {'name__n': ['Site 1']}
447448
self.assertEqual(SiteFilterSet(params, Site.objects.all()).qs.count(), 2)
448449

450+
def test_site_status_icontains(self):
451+
params = {'status__ic': [SiteStatusChoices.STATUS_ACTIVE]}
452+
self.assertEqual(SiteFilterSet(params, Site.objects.all()).qs.count(), 2)
453+
454+
def test_site_status_icontains_negation(self):
455+
params = {'status__nic': [SiteStatusChoices.STATUS_ACTIVE]}
456+
self.assertEqual(SiteFilterSet(params, Site.objects.all()).qs.count(), 1)
457+
449458
def test_site_slug_icontains(self):
450459
params = {'slug__ic': ['-1']}
451460
self.assertEqual(SiteFilterSet(params, Site.objects.all()).qs.count(), 1)
@@ -553,3 +562,9 @@ def test_device_mac_address_icontains(self):
553562
def test_device_mac_address_icontains_negation(self):
554563
params = {'mac_address__nic': ['aa:', 'bb']}
555564
self.assertEqual(DeviceFilterSet(params, Device.objects.all()).qs.count(), 1)
565+
566+
def test_interface_rf_role_empty(self):
567+
params = {'rf_role__empty': 'true'}
568+
self.assertEqual(InterfaceFilterSet(params, Interface.objects.all()).qs.count(), 5)
569+
params = {'rf_role__empty': 'false'}
570+
self.assertEqual(InterfaceFilterSet(params, Interface.objects.all()).qs.count(), 1)

0 commit comments

Comments
 (0)