Просмотр исходного кода

Fix filtering services by port number

Jeremy Stretch 5 лет назад
Родитель
Сommit
3a90366538
4 измененных файлов с 21 добавлено и 8 удалено
  1. 5 1
      netbox/ipam/filters.py
  2. 3 2
      netbox/ipam/tables.py
  3. 3 3
      netbox/ipam/tests/test_filters.py
  4. 10 2
      netbox/utilities/filters.py

+ 5 - 1
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:

+ 3 - 2
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'

+ 3 - 3
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]

+ 10 - 2
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: [<Region: R1>,<Region: R2>]
     """
-
     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
 #