فهرست منبع

Fixes #20468: Fix range lookups for numeric GraphQL filters (#21589)

* Fixes #20468: Fix range lookups for numeric GraphQL filters

* Update netbox/netbox/tests/test_graphql.py

---------

Co-authored-by: Martin Hauser <mhauser@netboxlabs.com>
Jeremy Stretch 11 ساعت پیش
والد
کامیت
fa5f9430fc
2فایلهای تغییر یافته به همراه44 افزوده شده و 1 حذف شده
  1. 9 0
      netbox/netbox/graphql/filter_lookups.py
  2. 35 1
      netbox/netbox/tests/test_graphql.py

+ 9 - 0
netbox/netbox/graphql/filter_lookups.py

@@ -79,6 +79,9 @@ class IntegerLookup:
         if not filters:
             return queryset, Q()
 
+        if isinstance(filters, RangeLookup):
+            prefix = f'{prefix}range__'
+
         return process_filters(filters=filters, queryset=queryset, info=info, prefix=prefix)
 
 
@@ -102,6 +105,9 @@ class BigIntegerLookup:
         if not filters:
             return queryset, Q()
 
+        if isinstance(filters, RangeLookup):
+            prefix = f'{prefix}range__'
+
         return process_filters(filters=filters, queryset=queryset, info=info, prefix=prefix)
 
 
@@ -125,6 +131,9 @@ class FloatLookup:
         if not filters:
             return queryset, Q()
 
+        if isinstance(filters, RangeLookup):
+            prefix = f'{prefix}range__'
+
         return process_filters(filters=filters, queryset=queryset, info=info, prefix=prefix)
 
 

+ 35 - 1
netbox/netbox/tests/test_graphql.py

@@ -5,7 +5,7 @@ from django.urls import reverse
 from rest_framework import status
 
 from dcim.choices import LocationStatusChoices
-from dcim.models import Location, Site
+from dcim.models import Device, DeviceRole, DeviceType, Location, Manufacturer, Site, VirtualChassis
 from utilities.testing import APITestCase, TestCase, disable_warnings
 
 
@@ -138,6 +138,40 @@ class GraphQLAPITestCase(APITestCase):
         self.assertNotIn('errors', data)
         self.assertEqual(len(data['data']['site']['locations']), 0)
 
+    def test_graphql_integer_range_lookup(self):
+        """
+        Test that range_lookup works for integer fields (e.g. vc_position). Regression test for #20468.
+        """
+        self.add_permissions('dcim.view_device')
+        url = reverse('graphql')
+
+        manufacturer = Manufacturer.objects.create(name='Test Manufacturer', slug='test-manufacturer')
+        device_type = DeviceType.objects.create(manufacturer=manufacturer, model='Test Device', slug='test-device')
+        device_role = DeviceRole.objects.create(name='Test Role', slug='test-role')
+        site = Site.objects.first()
+        vc = VirtualChassis.objects.create(name='Test VC')
+
+        devices = [
+            Device(name=f'Device {i}', device_type=device_type, role=device_role, site=site,
+                   virtual_chassis=vc, vc_position=i)
+            for i in range(1, 6)
+        ]
+        Device.objects.bulk_create(devices)
+
+        # range_lookup should return devices with vc_position between 2 and 4 inclusive
+        query = """
+        {
+            device_list(filters: {vc_position: {range_lookup: {start: 2, end: 4}}}) {
+                id name
+            }
+        }
+        """
+        response = self.client.post(url, data={'query': query}, format="json", **self.header)
+        self.assertHttpStatus(response, status.HTTP_200_OK)
+        data = json.loads(response.content)
+        self.assertNotIn('errors', data)
+        self.assertEqual(len(data['data']['device_list']), 3)
+
     def test_offset_pagination(self):
         self.add_permissions('dcim.view_site')
         url = reverse('graphql')