diff --git a/docs/release-notes/version-2.7.md b/docs/release-notes/version-2.7.md index 44298fec3f7..7992e9ae9ba 100644 --- a/docs/release-notes/version-2.7.md +++ b/docs/release-notes/version-2.7.md @@ -9,6 +9,7 @@ ## Bug Fixes +* [#3507](https://github.com/netbox-community/netbox/issues/3507) - Fix filtering IPaddress by multiple devices * [#4089](https://github.com/netbox-community/netbox/issues/4089) - Selection of power outlet type during bulk update is optional * [#4090](https://github.com/netbox-community/netbox/issues/4090) - Render URL custom fields as links under object view * [#4091](https://github.com/netbox-community/netbox/issues/4091) - Fix filtering of objects by custom fields using UI search form diff --git a/netbox/ipam/filters.py b/netbox/ipam/filters.py index 67ad769cc5b..5f8bcabff4b 100644 --- a/netbox/ipam/filters.py +++ b/netbox/ipam/filters.py @@ -8,7 +8,7 @@ from extras.filters import CustomFieldFilterSet, CreatedUpdatedFilterSet from tenancy.filters import TenancyFilterSet from utilities.filters import ( - MultiValueCharFilter, NameSlugSearchFilterSet, NumericInFilter, TagFilter, TreeNodeMultipleChoiceFilter, + MultiValueCharFilter, MultiValueNumberFilter, NameSlugSearchFilterSet, NumericInFilter, TagFilter, TreeNodeMultipleChoiceFilter, ) from virtualization.models import VirtualMachine from .choices import * @@ -304,12 +304,12 @@ class IPAddressFilterSet(TenancyFilterSet, CustomFieldFilterSet, CreatedUpdatedF to_field_name='rd', label='VRF (RD)', ) - device = django_filters.CharFilter( + device = MultiValueCharFilter( method='filter_device', field_name='name', - label='Device', + label='Device (name)', ) - device_id = django_filters.NumberFilter( + device_id = MultiValueNumberFilter( method='filter_device', field_name='pk', label='Device (ID)', @@ -385,8 +385,10 @@ def filter_mask_length(self, queryset, name, value): def filter_device(self, queryset, name, value): try: - device = Device.objects.prefetch_related('device_type').get(**{name: value}) - vc_interface_ids = [i['id'] for i in device.vc_interfaces.values('id')] + devices = Device.objects.prefetch_related('device_type').filter(**{'{}__in'.format(name): value}) + vc_interface_ids = [] + for device in devices: + vc_interface_ids.extend([i['id'] for i in device.vc_interfaces.values('id')]) return queryset.filter(interface_id__in=vc_interface_ids) except Device.DoesNotExist: return queryset.none() diff --git a/netbox/ipam/tests/test_filters.py b/netbox/ipam/tests/test_filters.py index 80ada0df8c1..4737a0f53f7 100644 --- a/netbox/ipam/tests/test_filters.py +++ b/netbox/ipam/tests/test_filters.py @@ -392,13 +392,12 @@ def test_vrf(self): params = {'vrf': [vrfs[0].rd, vrfs[1].rd]} self.assertEqual(self.filterset(params, self.queryset).qs.count(), 4) - # TODO: Test for multiple values def test_device(self): - device = Device.objects.first() - params = {'device_id': device.pk} - self.assertEqual(self.filterset(params, self.queryset).qs.count(), 1) - params = {'device': device.name} - self.assertEqual(self.filterset(params, self.queryset).qs.count(), 1) + devices = Device.objects.all()[:2] + params = {'device_id': [devices[0].pk, devices[1].pk]} + self.assertEqual(self.filterset(params, self.queryset).qs.count(), 2) + params = {'device': [devices[0].name, devices[1].name]} + self.assertEqual(self.filterset(params, self.queryset).qs.count(), 2) def test_virtual_machine(self): vms = VirtualMachine.objects.all()[:2]