Closes #4313: Remove id__in filters

This commit is contained in:
Jeremy Stretch 2020-03-06 12:05:53 -05:00
parent 1a89e35729
commit 803287a514
16 changed files with 8 additions and 182 deletions

View File

@ -7,6 +7,7 @@
## API Changes ## API Changes
* dcim.Rack: The `/api/dcim/racks/<pk>/units/` endpoint has been replaced with `/api/dcim/racks/<pk>/elevation/`. * dcim.Rack: The `/api/dcim/racks/<pk>/units/` endpoint has been replaced with `/api/dcim/racks/<pk>/elevation/`.
* The `id__in` filter has been removed. Use the format `?id=1&id=2` instead. ([#4313](https://github.com/netbox-community/netbox/issues/4313))
## Other Changes ## Other Changes

View File

@ -5,7 +5,7 @@ from dcim.models import Region, Site
from extras.filters import CustomFieldFilterSet, CreatedUpdatedFilterSet from extras.filters import CustomFieldFilterSet, CreatedUpdatedFilterSet
from tenancy.filters import TenancyFilterSet from tenancy.filters import TenancyFilterSet
from utilities.filters import ( from utilities.filters import (
BaseFilterSet, NameSlugSearchFilterSet, NumericInFilter, TagFilter, TreeNodeMultipleChoiceFilter BaseFilterSet, NameSlugSearchFilterSet, TagFilter, TreeNodeMultipleChoiceFilter
) )
from .choices import * from .choices import *
from .models import Circuit, CircuitTermination, CircuitType, Provider from .models import Circuit, CircuitTermination, CircuitType, Provider
@ -19,10 +19,6 @@ __all__ = (
class ProviderFilterSet(BaseFilterSet, CustomFieldFilterSet, CreatedUpdatedFilterSet): class ProviderFilterSet(BaseFilterSet, CustomFieldFilterSet, CreatedUpdatedFilterSet):
id__in = NumericInFilter(
field_name='id',
lookup_expr='in'
)
q = django_filters.CharFilter( q = django_filters.CharFilter(
method='search', method='search',
label='Search', label='Search',
@ -77,10 +73,6 @@ class CircuitTypeFilterSet(BaseFilterSet, NameSlugSearchFilterSet):
class CircuitFilterSet(BaseFilterSet, CustomFieldFilterSet, TenancyFilterSet, CreatedUpdatedFilterSet): class CircuitFilterSet(BaseFilterSet, CustomFieldFilterSet, TenancyFilterSet, CreatedUpdatedFilterSet):
id__in = NumericInFilter(
field_name='id',
lookup_expr='in'
)
q = django_filters.CharFilter( q = django_filters.CharFilter(
method='search', method='search',
label='Search', label='Search',

View File

@ -70,11 +70,6 @@ class ProviderTestCase(TestCase):
params = {'account': ['1234', '2345']} params = {'account': ['1234', '2345']}
self.assertEqual(self.filterset(params, self.queryset).qs.count(), 2) self.assertEqual(self.filterset(params, self.queryset).qs.count(), 2)
def test_id__in(self):
id_list = self.queryset.values_list('id', flat=True)[:3]
params = {'id__in': ','.join([str(id) for id in id_list])}
self.assertEqual(self.filterset(params, self.queryset).qs.count(), 3)
def test_site(self): def test_site(self):
sites = Site.objects.all()[:2] sites = Site.objects.all()[:2]
params = {'site_id': [sites[0].pk, sites[1].pk]} params = {'site_id': [sites[0].pk, sites[1].pk]}
@ -194,11 +189,6 @@ class CircuitTestCase(TestCase):
params = {'commit_rate': ['1000', '2000']} params = {'commit_rate': ['1000', '2000']}
self.assertEqual(self.filterset(params, self.queryset).qs.count(), 2) self.assertEqual(self.filterset(params, self.queryset).qs.count(), 2)
def test_id__in(self):
id_list = self.queryset.values_list('id', flat=True)[:3]
params = {'id__in': ','.join([str(id) for id in id_list])}
self.assertEqual(self.filterset(params, self.queryset).qs.count(), 3)
def test_provider(self): def test_provider(self):
provider = Provider.objects.first() provider = Provider.objects.first()
params = {'provider_id': [provider.pk]} params = {'provider_id': [provider.pk]}

View File

@ -7,7 +7,7 @@ from tenancy.models import Tenant
from utilities.constants import COLOR_CHOICES from utilities.constants import COLOR_CHOICES
from utilities.filters import ( from utilities.filters import (
BaseFilterSet, MultiValueCharFilter, MultiValueMACAddressFilter, MultiValueNumberFilter, BaseFilterSet, MultiValueCharFilter, MultiValueMACAddressFilter, MultiValueNumberFilter,
NameSlugSearchFilterSet, NumericInFilter, TagFilter, TreeNodeMultipleChoiceFilter, NameSlugSearchFilterSet, TagFilter, TreeNodeMultipleChoiceFilter,
) )
from virtualization.models import Cluster from virtualization.models import Cluster
from .choices import * from .choices import *
@ -78,10 +78,6 @@ class RegionFilterSet(BaseFilterSet, NameSlugSearchFilterSet):
class SiteFilterSet(BaseFilterSet, TenancyFilterSet, CustomFieldFilterSet, CreatedUpdatedFilterSet): class SiteFilterSet(BaseFilterSet, TenancyFilterSet, CustomFieldFilterSet, CreatedUpdatedFilterSet):
id__in = NumericInFilter(
field_name='id',
lookup_expr='in'
)
q = django_filters.CharFilter( q = django_filters.CharFilter(
method='search', method='search',
label='Search', label='Search',
@ -171,10 +167,6 @@ class RackRoleFilterSet(BaseFilterSet, NameSlugSearchFilterSet):
class RackFilterSet(BaseFilterSet, TenancyFilterSet, CustomFieldFilterSet, CreatedUpdatedFilterSet): class RackFilterSet(BaseFilterSet, TenancyFilterSet, CustomFieldFilterSet, CreatedUpdatedFilterSet):
id__in = NumericInFilter(
field_name='id',
lookup_expr='in'
)
q = django_filters.CharFilter( q = django_filters.CharFilter(
method='search', method='search',
label='Search', label='Search',
@ -251,10 +243,6 @@ class RackFilterSet(BaseFilterSet, TenancyFilterSet, CustomFieldFilterSet, Creat
class RackReservationFilterSet(BaseFilterSet, TenancyFilterSet): class RackReservationFilterSet(BaseFilterSet, TenancyFilterSet):
id__in = NumericInFilter(
field_name='id',
lookup_expr='in'
)
q = django_filters.CharFilter( q = django_filters.CharFilter(
method='search', method='search',
label='Search', label='Search',
@ -319,10 +307,6 @@ class ManufacturerFilterSet(BaseFilterSet, NameSlugSearchFilterSet):
class DeviceTypeFilterSet(BaseFilterSet, CustomFieldFilterSet, CreatedUpdatedFilterSet): class DeviceTypeFilterSet(BaseFilterSet, CustomFieldFilterSet, CreatedUpdatedFilterSet):
id__in = NumericInFilter(
field_name='id',
lookup_expr='in'
)
q = django_filters.CharFilter( q = django_filters.CharFilter(
method='search', method='search',
label='Search', label='Search',
@ -504,10 +488,6 @@ class DeviceFilterSet(
CustomFieldFilterSet, CustomFieldFilterSet,
CreatedUpdatedFilterSet CreatedUpdatedFilterSet
): ):
id__in = NumericInFilter(
field_name='id',
lookup_expr='in'
)
q = django_filters.CharFilter( q = django_filters.CharFilter(
method='search', method='search',
label='Search', label='Search',
@ -1236,10 +1216,6 @@ class InterfaceConnectionFilterSet(BaseFilterSet):
class PowerPanelFilterSet(BaseFilterSet): class PowerPanelFilterSet(BaseFilterSet):
id__in = NumericInFilter(
field_name='id',
lookup_expr='in'
)
q = django_filters.CharFilter( q = django_filters.CharFilter(
method='search', method='search',
label='Search', label='Search',
@ -1287,10 +1263,6 @@ class PowerPanelFilterSet(BaseFilterSet):
class PowerFeedFilterSet(BaseFilterSet, CustomFieldFilterSet, CreatedUpdatedFilterSet): class PowerFeedFilterSet(BaseFilterSet, CustomFieldFilterSet, CreatedUpdatedFilterSet):
id__in = NumericInFilter(
field_name='id',
lookup_expr='in'
)
q = django_filters.CharFilter( q = django_filters.CharFilter(
method='search', method='search',
label='Search', label='Search',

View File

@ -138,11 +138,6 @@ class SiteTestCase(TestCase):
params = {'contact_email': ['contact1@example.com', 'contact2@example.com']} params = {'contact_email': ['contact1@example.com', 'contact2@example.com']}
self.assertEqual(self.filterset(params, self.queryset).qs.count(), 2) self.assertEqual(self.filterset(params, self.queryset).qs.count(), 2)
def test_id__in(self):
id_list = self.queryset.values_list('id', flat=True)[:2]
params = {'id__in': ','.join([str(id) for id in id_list])}
self.assertEqual(self.filterset(params, self.queryset).qs.count(), 2)
def test_status(self): def test_status(self):
params = {'status': [SiteStatusChoices.STATUS_ACTIVE, SiteStatusChoices.STATUS_PLANNED]} params = {'status': [SiteStatusChoices.STATUS_ACTIVE, SiteStatusChoices.STATUS_PLANNED]}
self.assertEqual(self.filterset(params, self.queryset).qs.count(), 2) self.assertEqual(self.filterset(params, self.queryset).qs.count(), 2)
@ -365,11 +360,6 @@ class RackTestCase(TestCase):
params = {'outer_unit': RackDimensionUnitChoices.UNIT_MILLIMETER} params = {'outer_unit': RackDimensionUnitChoices.UNIT_MILLIMETER}
self.assertEqual(self.filterset(params, self.queryset).qs.count(), 2) self.assertEqual(self.filterset(params, self.queryset).qs.count(), 2)
def test_id__in(self):
id_list = self.queryset.values_list('id', flat=True)[:2]
params = {'id__in': ','.join([str(id) for id in id_list])}
self.assertEqual(self.filterset(params, self.queryset).qs.count(), 2)
def test_region(self): def test_region(self):
regions = Region.objects.all()[:2] regions = Region.objects.all()[:2]
params = {'region_id': [regions[0].pk, regions[1].pk]} params = {'region_id': [regions[0].pk, regions[1].pk]}
@ -479,11 +469,6 @@ class RackReservationTestCase(TestCase):
) )
RackReservation.objects.bulk_create(reservations) RackReservation.objects.bulk_create(reservations)
def test_id__in(self):
id_list = self.queryset.values_list('id', flat=True)[:2]
params = {'id__in': ','.join([str(id) for id in id_list])}
self.assertEqual(self.filterset(params, self.queryset).qs.count(), 2)
def test_site(self): def test_site(self):
sites = Site.objects.all()[:2] sites = Site.objects.all()[:2]
params = {'site_id': [sites[0].pk, sites[1].pk]} params = {'site_id': [sites[0].pk, sites[1].pk]}
@ -631,11 +616,6 @@ class DeviceTypeTestCase(TestCase):
params = {'subdevice_role': SubdeviceRoleChoices.ROLE_PARENT} params = {'subdevice_role': SubdeviceRoleChoices.ROLE_PARENT}
self.assertEqual(self.filterset(params, self.queryset).qs.count(), 1) self.assertEqual(self.filterset(params, self.queryset).qs.count(), 1)
def test_id__in(self):
id_list = self.queryset.values_list('id', flat=True)[:2]
params = {'id__in': ','.join([str(id) for id in id_list])}
self.assertEqual(self.filterset(params, self.queryset).qs.count(), 2)
def test_manufacturer(self): def test_manufacturer(self):
manufacturers = Manufacturer.objects.all()[:2] manufacturers = Manufacturer.objects.all()[:2]
params = {'manufacturer_id': [manufacturers[0].pk, manufacturers[1].pk]} params = {'manufacturer_id': [manufacturers[0].pk, manufacturers[1].pk]}
@ -1283,11 +1263,6 @@ class DeviceTestCase(TestCase):
params = {'vc_priority': [1, 2]} params = {'vc_priority': [1, 2]}
self.assertEqual(self.filterset(params, self.queryset).qs.count(), 2) self.assertEqual(self.filterset(params, self.queryset).qs.count(), 2)
def test_id__in(self):
id_list = self.queryset.values_list('id', flat=True)[:2]
params = {'id__in': ','.join([str(id) for id in id_list])}
self.assertEqual(self.filterset(params, self.queryset).qs.count(), 2)
def test_manufacturer(self): def test_manufacturer(self):
manufacturers = Manufacturer.objects.all()[:2] manufacturers = Manufacturer.objects.all()[:2]
params = {'manufacturer_id': [manufacturers[0].pk, manufacturers[1].pk]} params = {'manufacturer_id': [manufacturers[0].pk, manufacturers[1].pk]}

View File

@ -8,8 +8,8 @@ from dcim.models import Device, Interface, Region, Site
from extras.filters import CustomFieldFilterSet, CreatedUpdatedFilterSet from extras.filters import CustomFieldFilterSet, CreatedUpdatedFilterSet
from tenancy.filters import TenancyFilterSet from tenancy.filters import TenancyFilterSet
from utilities.filters import ( from utilities.filters import (
BaseFilterSet, MultiValueCharFilter, MultiValueNumberFilter, NameSlugSearchFilterSet, BaseFilterSet, MultiValueCharFilter, MultiValueNumberFilter, NameSlugSearchFilterSet, TagFilter,
NumericInFilter, TagFilter, TreeNodeMultipleChoiceFilter, TreeNodeMultipleChoiceFilter,
) )
from virtualization.models import VirtualMachine from virtualization.models import VirtualMachine
from .choices import * from .choices import *
@ -30,10 +30,6 @@ __all__ = (
class VRFFilterSet(BaseFilterSet, TenancyFilterSet, CustomFieldFilterSet, CreatedUpdatedFilterSet): class VRFFilterSet(BaseFilterSet, TenancyFilterSet, CustomFieldFilterSet, CreatedUpdatedFilterSet):
id__in = NumericInFilter(
field_name='id',
lookup_expr='in'
)
q = django_filters.CharFilter( q = django_filters.CharFilter(
method='search', method='search',
label='Search', label='Search',
@ -55,10 +51,6 @@ class VRFFilterSet(BaseFilterSet, TenancyFilterSet, CustomFieldFilterSet, Create
class RIRFilterSet(BaseFilterSet, NameSlugSearchFilterSet): class RIRFilterSet(BaseFilterSet, NameSlugSearchFilterSet):
id__in = NumericInFilter(
field_name='id',
lookup_expr='in'
)
class Meta: class Meta:
model = RIR model = RIR
@ -66,10 +58,6 @@ class RIRFilterSet(BaseFilterSet, NameSlugSearchFilterSet):
class AggregateFilterSet(BaseFilterSet, CustomFieldFilterSet, CreatedUpdatedFilterSet): class AggregateFilterSet(BaseFilterSet, CustomFieldFilterSet, CreatedUpdatedFilterSet):
id__in = NumericInFilter(
field_name='id',
lookup_expr='in'
)
q = django_filters.CharFilter( q = django_filters.CharFilter(
method='search', method='search',
label='Search', label='Search',
@ -131,10 +119,6 @@ class RoleFilterSet(BaseFilterSet, NameSlugSearchFilterSet):
class PrefixFilterSet(BaseFilterSet, TenancyFilterSet, CustomFieldFilterSet, CreatedUpdatedFilterSet): class PrefixFilterSet(BaseFilterSet, TenancyFilterSet, CustomFieldFilterSet, CreatedUpdatedFilterSet):
id__in = NumericInFilter(
field_name='id',
lookup_expr='in'
)
q = django_filters.CharFilter( q = django_filters.CharFilter(
method='search', method='search',
label='Search', label='Search',
@ -285,10 +269,6 @@ class PrefixFilterSet(BaseFilterSet, TenancyFilterSet, CustomFieldFilterSet, Cre
class IPAddressFilterSet(BaseFilterSet, TenancyFilterSet, CustomFieldFilterSet, CreatedUpdatedFilterSet): class IPAddressFilterSet(BaseFilterSet, TenancyFilterSet, CustomFieldFilterSet, CreatedUpdatedFilterSet):
id__in = NumericInFilter(
field_name='id',
lookup_expr='in'
)
q = django_filters.CharFilter( q = django_filters.CharFilter(
method='search', method='search',
label='Search', label='Search',
@ -443,10 +423,6 @@ class VLANGroupFilterSet(BaseFilterSet, NameSlugSearchFilterSet):
class VLANFilterSet(BaseFilterSet, TenancyFilterSet, CustomFieldFilterSet, CreatedUpdatedFilterSet): class VLANFilterSet(BaseFilterSet, TenancyFilterSet, CustomFieldFilterSet, CreatedUpdatedFilterSet):
id__in = NumericInFilter(
field_name='id',
lookup_expr='in'
)
q = django_filters.CharFilter( q = django_filters.CharFilter(
method='search', method='search',
label='Search', label='Search',

View File

@ -53,11 +53,6 @@ class VRFTestCase(TestCase):
params = {'enforce_unique': 'false'} params = {'enforce_unique': 'false'}
self.assertEqual(self.filterset(params, self.queryset).qs.count(), 3) self.assertEqual(self.filterset(params, self.queryset).qs.count(), 3)
def test_id__in(self):
id_list = self.queryset.values_list('id', flat=True)[:3]
params = {'id__in': ','.join([str(id) for id in id_list])}
self.assertEqual(self.filterset(params, self.queryset).qs.count(), 3)
def test_tenant(self): def test_tenant(self):
tenants = Tenant.objects.all()[:2] tenants = Tenant.objects.all()[:2]
params = {'tenant_id': [tenants[0].pk, tenants[1].pk]} params = {'tenant_id': [tenants[0].pk, tenants[1].pk]}
@ -104,11 +99,6 @@ class RIRTestCase(TestCase):
params = {'is_private': 'false'} params = {'is_private': 'false'}
self.assertEqual(self.filterset(params, self.queryset).qs.count(), 3) self.assertEqual(self.filterset(params, self.queryset).qs.count(), 3)
def test_id__in(self):
id_list = self.queryset.values_list('id', flat=True)[:3]
params = {'id__in': ','.join([str(id) for id in id_list])}
self.assertEqual(self.filterset(params, self.queryset).qs.count(), 3)
class AggregateTestCase(TestCase): class AggregateTestCase(TestCase):
queryset = Aggregate.objects.all() queryset = Aggregate.objects.all()
@ -265,11 +255,6 @@ class PrefixTestCase(TestCase):
params = {'is_pool': 'false'} params = {'is_pool': 'false'}
self.assertEqual(self.filterset(params, self.queryset).qs.count(), 8) self.assertEqual(self.filterset(params, self.queryset).qs.count(), 8)
def test_id__in(self):
id_list = self.queryset.values_list('id', flat=True)[:3]
params = {'id__in': ','.join([str(id) for id in id_list])}
self.assertEqual(self.filterset(params, self.queryset).qs.count(), 3)
def test_within(self): def test_within(self):
params = {'within': '10.0.0.0/16'} params = {'within': '10.0.0.0/16'}
self.assertEqual(self.filterset(params, self.queryset).qs.count(), 4) self.assertEqual(self.filterset(params, self.queryset).qs.count(), 4)
@ -425,11 +410,6 @@ class IPAddressTestCase(TestCase):
params = {'dns_name': ['ipaddress-a', 'ipaddress-b']} params = {'dns_name': ['ipaddress-a', 'ipaddress-b']}
self.assertEqual(self.filterset(params, self.queryset).qs.count(), 4) self.assertEqual(self.filterset(params, self.queryset).qs.count(), 4)
def test_id__in(self):
id_list = self.queryset.values_list('id', flat=True)[:3]
params = {'id__in': ','.join([str(id) for id in id_list])}
self.assertEqual(self.filterset(params, self.queryset).qs.count(), 3)
def test_parent(self): def test_parent(self):
params = {'parent': '10.0.0.0/24'} params = {'parent': '10.0.0.0/24'}
self.assertEqual(self.filterset(params, self.queryset).qs.count(), 5) self.assertEqual(self.filterset(params, self.queryset).qs.count(), 5)
@ -640,11 +620,6 @@ class VLANTestCase(TestCase):
params = {'vid': ['101', '201', '301']} params = {'vid': ['101', '201', '301']}
self.assertEqual(self.filterset(params, self.queryset).qs.count(), 3) self.assertEqual(self.filterset(params, self.queryset).qs.count(), 3)
def test_id__in(self):
id_list = self.queryset.values_list('id', flat=True)[:3]
params = {'id__in': ','.join([str(id) for id in id_list])}
self.assertEqual(self.filterset(params, self.queryset).qs.count(), 3)
def test_region(self): def test_region(self):
regions = Region.objects.all()[:2] regions = Region.objects.all()[:2]
params = {'region_id': [regions[0].pk, regions[1].pk]} params = {'region_id': [regions[0].pk, regions[1].pk]}

View File

@ -522,7 +522,6 @@ SWAGGER_SETTINGS = {
'drf_yasg.inspectors.StringDefaultFieldInspector', 'drf_yasg.inspectors.StringDefaultFieldInspector',
], ],
'DEFAULT_FILTER_INSPECTORS': [ 'DEFAULT_FILTER_INSPECTORS': [
'utilities.custom_inspectors.IdInFilterInspector',
'drf_yasg.inspectors.CoreAPICompatInspector', 'drf_yasg.inspectors.CoreAPICompatInspector',
], ],
'DEFAULT_INFO': 'netbox.urls.openapi_info', 'DEFAULT_INFO': 'netbox.urls.openapi_info',

View File

@ -3,7 +3,7 @@ from django.db.models import Q
from dcim.models import Device from dcim.models import Device
from extras.filters import CustomFieldFilterSet, CreatedUpdatedFilterSet from extras.filters import CustomFieldFilterSet, CreatedUpdatedFilterSet
from utilities.filters import BaseFilterSet, NameSlugSearchFilterSet, NumericInFilter, TagFilter from utilities.filters import BaseFilterSet, NameSlugSearchFilterSet, TagFilter
from .models import Secret, SecretRole from .models import Secret, SecretRole
@ -21,10 +21,6 @@ class SecretRoleFilterSet(BaseFilterSet, NameSlugSearchFilterSet):
class SecretFilterSet(BaseFilterSet, CustomFieldFilterSet, CreatedUpdatedFilterSet): class SecretFilterSet(BaseFilterSet, CustomFieldFilterSet, CreatedUpdatedFilterSet):
id__in = NumericInFilter(
field_name='id',
lookup_expr='in'
)
q = django_filters.CharFilter( q = django_filters.CharFilter(
method='search', method='search',
label='Search', label='Search',

View File

@ -72,11 +72,6 @@ class SecretTestCase(TestCase):
params = {'name': ['Secret 1', 'Secret 2']} params = {'name': ['Secret 1', 'Secret 2']}
self.assertEqual(self.filterset(params, self.queryset).qs.count(), 2) self.assertEqual(self.filterset(params, self.queryset).qs.count(), 2)
def test_id__in(self):
id_list = self.queryset.values_list('id', flat=True)[:2]
params = {'id__in': ','.join([str(id) for id in id_list])}
self.assertEqual(self.filterset(params, self.queryset).qs.count(), 2)
def test_role(self): def test_role(self):
roles = SecretRole.objects.all()[:2] roles = SecretRole.objects.all()[:2]
params = {'role_id': [roles[0].pk, roles[1].pk]} params = {'role_id': [roles[0].pk, roles[1].pk]}

View File

@ -2,7 +2,7 @@ import django_filters
from django.db.models import Q from django.db.models import Q
from extras.filters import CustomFieldFilterSet, CreatedUpdatedFilterSet from extras.filters import CustomFieldFilterSet, CreatedUpdatedFilterSet
from utilities.filters import BaseFilterSet, NameSlugSearchFilterSet, NumericInFilter, TagFilter from utilities.filters import BaseFilterSet, NameSlugSearchFilterSet, TagFilter
from .models import Tenant, TenantGroup from .models import Tenant, TenantGroup
@ -21,10 +21,6 @@ class TenantGroupFilterSet(BaseFilterSet, NameSlugSearchFilterSet):
class TenantFilterSet(BaseFilterSet, CustomFieldFilterSet, CreatedUpdatedFilterSet): class TenantFilterSet(BaseFilterSet, CustomFieldFilterSet, CreatedUpdatedFilterSet):
id__in = NumericInFilter(
field_name='id',
lookup_expr='in'
)
q = django_filters.CharFilter( q = django_filters.CharFilter(
method='search', method='search',
label='Search', label='Search',

View File

@ -61,11 +61,6 @@ class TenantTestCase(TestCase):
params = {'slug': ['tenant-1', 'tenant-2']} params = {'slug': ['tenant-1', 'tenant-2']}
self.assertEqual(self.filterset(params, self.queryset).qs.count(), 2) self.assertEqual(self.filterset(params, self.queryset).qs.count(), 2)
def test_id__in(self):
id_list = self.queryset.values_list('id', flat=True)[:2]
params = {'id__in': ','.join([str(id) for id in id_list])}
self.assertEqual(self.filterset(params, self.queryset).qs.count(), 2)
def test_group(self): def test_group(self):
group = TenantGroup.objects.all()[:2] group = TenantGroup.objects.all()[:2]
params = {'group_id': [group[0].pk, group[1].pk]} params = {'group_id': [group[0].pk, group[1].pk]}

View File

@ -131,16 +131,6 @@ class JSONFieldInspector(FieldInspector):
return result return result
class IdInFilterInspector(FilterInspector):
def process_result(self, result, method_name, obj, **kwargs):
if isinstance(result, list):
params = [p for p in result if isinstance(p, openapi.Parameter) and p.name == 'id__in']
for p in params:
p.type = 'string'
return result
class NullablePaginatorInspector(PaginatorInspector): class NullablePaginatorInspector(PaginatorInspector):
def process_result(self, result, method_name, obj, **kwargs): def process_result(self, result, method_name, obj, **kwargs):
if method_name == 'get_paginated_response' and isinstance(result, openapi.Schema): if method_name == 'get_paginated_response' and isinstance(result, openapi.Schema):

View File

@ -80,13 +80,6 @@ class TreeNodeMultipleChoiceFilter(django_filters.ModelMultipleChoiceFilter):
return super().filter(qs, value) return super().filter(qs, value)
class NumericInFilter(django_filters.BaseInFilter, django_filters.NumberFilter):
"""
Filters for a set of numeric values. Example: id__in=100,200,300
"""
pass
class NullableCharFieldFilter(django_filters.CharFilter): class NullableCharFieldFilter(django_filters.CharFilter):
""" """
Allow matching on null field values by passing a special string used to signify NULL. Allow matching on null field values by passing a special string used to signify NULL.

View File

@ -4,9 +4,8 @@ from django.db.models import Q
from dcim.models import DeviceRole, Interface, Platform, Region, Site from dcim.models import DeviceRole, Interface, Platform, Region, Site
from extras.filters import CustomFieldFilterSet, CreatedUpdatedFilterSet, LocalConfigContextFilterSet from extras.filters import CustomFieldFilterSet, CreatedUpdatedFilterSet, LocalConfigContextFilterSet
from tenancy.filters import TenancyFilterSet from tenancy.filters import TenancyFilterSet
from tenancy.models import Tenant
from utilities.filters import ( from utilities.filters import (
BaseFilterSet, MultiValueMACAddressFilter, NameSlugSearchFilterSet, NumericInFilter, TagFilter, BaseFilterSet, MultiValueMACAddressFilter, NameSlugSearchFilterSet, TagFilter,
TreeNodeMultipleChoiceFilter, TreeNodeMultipleChoiceFilter,
) )
from .choices import * from .choices import *
@ -36,10 +35,6 @@ class ClusterGroupFilterSet(BaseFilterSet, NameSlugSearchFilterSet):
class ClusterFilterSet(BaseFilterSet, TenancyFilterSet, CustomFieldFilterSet, CreatedUpdatedFilterSet): class ClusterFilterSet(BaseFilterSet, TenancyFilterSet, CustomFieldFilterSet, CreatedUpdatedFilterSet):
id__in = NumericInFilter(
field_name='id',
lookup_expr='in'
)
q = django_filters.CharFilter( q = django_filters.CharFilter(
method='search', method='search',
label='Search', label='Search',
@ -109,10 +104,6 @@ class VirtualMachineFilterSet(
CustomFieldFilterSet, CustomFieldFilterSet,
CreatedUpdatedFilterSet CreatedUpdatedFilterSet
): ):
id__in = NumericInFilter(
field_name='id',
lookup_expr='in'
)
q = django_filters.CharFilter( q = django_filters.CharFilter(
method='search', method='search',
label='Search', label='Search',

View File

@ -125,11 +125,6 @@ class ClusterTestCase(TestCase):
params = {'name': ['Cluster 1', 'Cluster 2']} params = {'name': ['Cluster 1', 'Cluster 2']}
self.assertEqual(self.filterset(params, self.queryset).qs.count(), 2) self.assertEqual(self.filterset(params, self.queryset).qs.count(), 2)
def test_id__in(self):
id_list = self.queryset.values_list('id', flat=True)[:2]
params = {'id__in': ','.join([str(id) for id in id_list])}
self.assertEqual(self.filterset(params, self.queryset).qs.count(), 2)
def test_region(self): def test_region(self):
regions = Region.objects.all()[:2] regions = Region.objects.all()[:2]
params = {'region_id': [regions[0].pk, regions[1].pk]} params = {'region_id': [regions[0].pk, regions[1].pk]}
@ -280,11 +275,6 @@ class VirtualMachineTestCase(TestCase):
params = {'disk': [1, 2]} params = {'disk': [1, 2]}
self.assertEqual(self.filterset(params, self.queryset).qs.count(), 2) self.assertEqual(self.filterset(params, self.queryset).qs.count(), 2)
def test_id__in(self):
id_list = self.queryset.values_list('id', flat=True)[:2]
params = {'id__in': ','.join([str(id) for id in id_list])}
self.assertEqual(self.filterset(params, self.queryset).qs.count(), 2)
def test_status(self): def test_status(self):
params = {'status': [VirtualMachineStatusChoices.STATUS_ACTIVE, VirtualMachineStatusChoices.STATUS_STAGED]} params = {'status': [VirtualMachineStatusChoices.STATUS_ACTIVE, VirtualMachineStatusChoices.STATUS_STAGED]}
self.assertEqual(self.filterset(params, self.queryset).qs.count(), 2) self.assertEqual(self.filterset(params, self.queryset).qs.count(), 2)