From 3a90366538d935edf110d8b7c1c3ad0b17ccadef Mon Sep 17 00:00:00 2001 From: Jeremy Stretch Date: Mon, 21 Sep 2020 14:36:58 -0400 Subject: [PATCH] Fix filtering services by port number --- netbox/ipam/filters.py | 6 +++++- netbox/ipam/tables.py | 5 +++-- netbox/ipam/tests/test_filters.py | 6 +++--- netbox/utilities/filters.py | 12 ++++++++++-- 4 files changed, 21 insertions(+), 8 deletions(-) diff --git a/netbox/ipam/filters.py b/netbox/ipam/filters.py index 7b85c7bf3..69453ea6c 100644 --- a/netbox/ipam/filters.py +++ b/netbox/ipam/filters.py @@ -8,7 +8,7 @@ from dcim.models import Device, Interface, Region, Site from extras.filters import CustomFieldFilterSet, CreatedUpdatedFilterSet from tenancy.filters import TenancyFilterSet from utilities.filters import ( - BaseFilterSet, MultiValueCharFilter, MultiValueNumberFilter, NameSlugSearchFilterSet, TagFilter, + BaseFilterSet, MultiValueCharFilter, MultiValueNumberFilter, NameSlugSearchFilterSet, NumericArrayFilter, TagFilter, TreeNodeMultipleChoiceFilter, ) from virtualization.models import VirtualMachine, VMInterface @@ -542,6 +542,10 @@ class ServiceFilterSet(BaseFilterSet, CreatedUpdatedFilterSet): to_field_name='name', label='Virtual machine (name)', ) + port = NumericArrayFilter( + field_name='ports', + lookup_expr='contains' + ) tag = TagFilter() class Meta: diff --git a/netbox/ipam/tables.py b/netbox/ipam/tables.py index e454e7850..532b0bcad 100644 --- a/netbox/ipam/tables.py +++ b/netbox/ipam/tables.py @@ -623,8 +623,9 @@ class ServiceTable(BaseTable): parent = tables.LinkColumn( order_by=('device', 'virtual_machine') ) - ports = tables.Column( - orderable=False + ports = tables.TemplateColumn( + template_code='{{ record.port_list }}', + verbose_name='Ports' ) tags = TagColumn( url_name='ipam:service_list' diff --git a/netbox/ipam/tests/test_filters.py b/netbox/ipam/tests/test_filters.py index 91d878a01..1ecf5a486 100644 --- a/netbox/ipam/tests/test_filters.py +++ b/netbox/ipam/tests/test_filters.py @@ -763,9 +763,9 @@ class ServiceTestCase(TestCase): params = {'protocol': ServiceProtocolChoices.PROTOCOL_TCP} self.assertEqual(self.filterset(params, self.queryset).qs.count(), 4) - # def test_port(self): - # params = {'port': ['1001', '1002', '1003']} - # self.assertEqual(self.filterset(params, self.queryset).qs.count(), 3) + def test_port(self): + params = {'port': '1001'} + self.assertEqual(self.filterset(params, self.queryset).qs.count(), 1) def test_device(self): devices = Device.objects.all()[:2] diff --git a/netbox/utilities/filters.py b/netbox/utilities/filters.py index f628ca917..69ddbf704 100644 --- a/netbox/utilities/filters.py +++ b/netbox/utilities/filters.py @@ -68,7 +68,6 @@ class TreeNodeMultipleChoiceFilter(django_filters.ModelMultipleChoiceFilter): """ Filters for a set of Models, including all descendant models within a Tree. Example: [,] """ - def get_filter_predicate(self, v): # null value filtering if v is None: @@ -84,7 +83,6 @@ class NullableCharFieldFilter(django_filters.CharFilter): """ Allow matching on null field values by passing a special string used to signify NULL. """ - def filter(self, qs, value): if value != settings.FILTERS_NULL_CHOICE_VALUE: return super().filter(qs, value) @@ -107,6 +105,16 @@ class TagFilter(django_filters.ModelMultipleChoiceFilter): super().__init__(*args, **kwargs) +class NumericArrayFilter(django_filters.NumberFilter): + """ + Filter based on the presence of an integer within an ArrayField. + """ + def filter(self, qs, value): + if value: + value = [value] + return super().filter(qs, value) + + # # FilterSets #