mirror of
https://github.com/netbox-community/netbox.git
synced 2025-07-14 01:41:22 -06:00
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
This commit is contained in:
parent
dda7837069
commit
ce04ec20e8
@ -180,9 +180,11 @@ class BaseFilterSet(django_filters.FilterSet):
|
|||||||
# create the new filter with the same type because there is no guarantee the defined type
|
# create the new filter with the same type because there is no guarantee the defined type
|
||||||
# is the same as the default type for the field
|
# is the same as the default type for the field
|
||||||
resolve_field(field, lookup_expr) # Will raise FieldLookupError if the lookup is invalid
|
resolve_field(field, lookup_expr) # Will raise FieldLookupError if the lookup is invalid
|
||||||
for field_to_remove in ('choices', 'null_value'):
|
filter_cls = type(existing_filter)
|
||||||
existing_filter_extra.pop(field_to_remove, None)
|
if lookup_expr == 'empty':
|
||||||
filter_cls = django_filters.BooleanFilter if lookup_expr == 'empty' else type(existing_filter)
|
filter_cls = django_filters.BooleanFilter
|
||||||
|
for param_to_remove in ('choices', 'null_value'):
|
||||||
|
existing_filter_extra.pop(param_to_remove, None)
|
||||||
new_filter = filter_cls(
|
new_filter = filter_cls(
|
||||||
field_name=field_name,
|
field_name=field_name,
|
||||||
lookup_expr=lookup_expr,
|
lookup_expr=lookup_expr,
|
||||||
|
@ -7,7 +7,7 @@ from taggit.managers import TaggableManager
|
|||||||
|
|
||||||
from dcim.choices import *
|
from dcim.choices import *
|
||||||
from dcim.fields import MACAddressField
|
from dcim.fields import MACAddressField
|
||||||
from dcim.filtersets import DeviceFilterSet, SiteFilterSet
|
from dcim.filtersets import DeviceFilterSet, SiteFilterSet, InterfaceFilterSet
|
||||||
from dcim.models import (
|
from dcim.models import (
|
||||||
Device, DeviceRole, DeviceType, Interface, Manufacturer, Platform, Rack, Region, Site
|
Device, DeviceRole, DeviceType, Interface, Manufacturer, Platform, Rack, Region, Site
|
||||||
)
|
)
|
||||||
@ -16,6 +16,7 @@ from extras.models import TaggedItem
|
|||||||
from ipam.filtersets import ASNFilterSet
|
from ipam.filtersets import ASNFilterSet
|
||||||
from ipam.models import RIR, ASN
|
from ipam.models import RIR, ASN
|
||||||
from netbox.filtersets import BaseFilterSet
|
from netbox.filtersets import BaseFilterSet
|
||||||
|
from wireless.choices import WirelessRoleChoices
|
||||||
from utilities.filters import (
|
from utilities.filters import (
|
||||||
MultiValueCharFilter, MultiValueDateFilter, MultiValueDateTimeFilter, MultiValueMACAddressFilter,
|
MultiValueCharFilter, MultiValueDateFilter, MultiValueDateTimeFilter, MultiValueMACAddressFilter,
|
||||||
MultiValueNumberFilter, MultiValueTimeFilter, TreeNodeMultipleChoiceFilter,
|
MultiValueNumberFilter, MultiValueTimeFilter, TreeNodeMultipleChoiceFilter,
|
||||||
@ -408,9 +409,9 @@ class DynamicFilterLookupExpressionTest(TestCase):
|
|||||||
region.save()
|
region.save()
|
||||||
|
|
||||||
sites = (
|
sites = (
|
||||||
Site(name='Site 1', slug='abc-site-1', region=regions[0]),
|
Site(name='Site 1', slug='abc-site-1', region=regions[0], status=SiteStatusChoices.STATUS_ACTIVE),
|
||||||
Site(name='Site 2', slug='def-site-2', region=regions[1]),
|
Site(name='Site 2', slug='def-site-2', region=regions[1], status=SiteStatusChoices.STATUS_ACTIVE),
|
||||||
Site(name='Site 3', slug='ghi-site-3', region=regions[2]),
|
Site(name='Site 3', slug='ghi-site-3', region=regions[2], status=SiteStatusChoices.STATUS_PLANNED),
|
||||||
)
|
)
|
||||||
Site.objects.bulk_create(sites)
|
Site.objects.bulk_create(sites)
|
||||||
|
|
||||||
@ -438,7 +439,7 @@ class DynamicFilterLookupExpressionTest(TestCase):
|
|||||||
Interface(device=devices[1], name='Interface 3', mac_address='00-00-00-00-00-02'),
|
Interface(device=devices[1], name='Interface 3', mac_address='00-00-00-00-00-02'),
|
||||||
Interface(device=devices[1], name='Interface 4', mac_address='bb-00-00-00-00-02'),
|
Interface(device=devices[1], name='Interface 4', mac_address='bb-00-00-00-00-02'),
|
||||||
Interface(device=devices[2], name='Interface 5', mac_address='00-00-00-00-00-03'),
|
Interface(device=devices[2], name='Interface 5', mac_address='00-00-00-00-00-03'),
|
||||||
Interface(device=devices[2], name='Interface 6', mac_address='cc-00-00-00-00-03'),
|
Interface(device=devices[2], name='Interface 6', mac_address='cc-00-00-00-00-03', rf_role=WirelessRoleChoices.ROLE_AP),
|
||||||
)
|
)
|
||||||
Interface.objects.bulk_create(interfaces)
|
Interface.objects.bulk_create(interfaces)
|
||||||
|
|
||||||
@ -446,6 +447,14 @@ class DynamicFilterLookupExpressionTest(TestCase):
|
|||||||
params = {'name__n': ['Site 1']}
|
params = {'name__n': ['Site 1']}
|
||||||
self.assertEqual(SiteFilterSet(params, Site.objects.all()).qs.count(), 2)
|
self.assertEqual(SiteFilterSet(params, Site.objects.all()).qs.count(), 2)
|
||||||
|
|
||||||
|
def test_site_status_icontains(self):
|
||||||
|
params = {'status__ic': [SiteStatusChoices.STATUS_ACTIVE]}
|
||||||
|
self.assertEqual(SiteFilterSet(params, Site.objects.all()).qs.count(), 2)
|
||||||
|
|
||||||
|
def test_site_status_icontains_negation(self):
|
||||||
|
params = {'status__nic': [SiteStatusChoices.STATUS_ACTIVE]}
|
||||||
|
self.assertEqual(SiteFilterSet(params, Site.objects.all()).qs.count(), 1)
|
||||||
|
|
||||||
def test_site_slug_icontains(self):
|
def test_site_slug_icontains(self):
|
||||||
params = {'slug__ic': ['-1']}
|
params = {'slug__ic': ['-1']}
|
||||||
self.assertEqual(SiteFilterSet(params, Site.objects.all()).qs.count(), 1)
|
self.assertEqual(SiteFilterSet(params, Site.objects.all()).qs.count(), 1)
|
||||||
@ -553,3 +562,9 @@ class DynamicFilterLookupExpressionTest(TestCase):
|
|||||||
def test_device_mac_address_icontains_negation(self):
|
def test_device_mac_address_icontains_negation(self):
|
||||||
params = {'mac_address__nic': ['aa:', 'bb']}
|
params = {'mac_address__nic': ['aa:', 'bb']}
|
||||||
self.assertEqual(DeviceFilterSet(params, Device.objects.all()).qs.count(), 1)
|
self.assertEqual(DeviceFilterSet(params, Device.objects.all()).qs.count(), 1)
|
||||||
|
|
||||||
|
def test_interface_rf_role_empty(self):
|
||||||
|
params = {'rf_role__empty': 'true'}
|
||||||
|
self.assertEqual(InterfaceFilterSet(params, Interface.objects.all()).qs.count(), 5)
|
||||||
|
params = {'rf_role__empty': 'false'}
|
||||||
|
self.assertEqual(InterfaceFilterSet(params, Interface.objects.all()).qs.count(), 1)
|
||||||
|
Loading…
Reference in New Issue
Block a user