22766 - Map GraphQL array length lookup to Django's len transform
This commit is contained in:
parent
ba5018a3b4
commit
f8e7950004
|
|
@ -306,10 +306,24 @@ class ArrayLookup(Generic[T]):
|
|||
Class for Array field lookups
|
||||
"""
|
||||
|
||||
contains: list[T] | None = strawberry_django.filter_field(description='Contains the value')
|
||||
contained_by: list[T] | None = strawberry_django.filter_field(description='Contained by the value')
|
||||
overlap: list[T] | None = strawberry_django.filter_field(description='Overlaps with the value')
|
||||
length: int | None = strawberry_django.filter_field(description='Length of the array')
|
||||
contains: list[T] | None = strawberry.field(default=strawberry.UNSET, description='Contains the value')
|
||||
contained_by: list[T] | None = strawberry.field(default=strawberry.UNSET, description='Contained by the value')
|
||||
overlap: list[T] | None = strawberry.field(default=strawberry.UNSET, description='Overlaps with the value')
|
||||
length: int | None = strawberry.field(default=strawberry.UNSET, description='Length of the array')
|
||||
|
||||
@strawberry_django.filter_field
|
||||
def filter(self, info: Info, queryset: QuerySet, prefix: str = '') -> tuple[QuerySet, Q]:
|
||||
# Map the public GraphQL ``length`` field to Django's ``len`` array transform; the
|
||||
# remaining lookups share their name with the corresponding ORM transform.
|
||||
if self.contains is not strawberry.UNSET and self.contains is not None:
|
||||
return queryset, Q(**{f'{prefix}contains': self.contains})
|
||||
if self.contained_by is not strawberry.UNSET and self.contained_by is not None:
|
||||
return queryset, Q(**{f'{prefix}contained_by': self.contained_by})
|
||||
if self.overlap is not strawberry.UNSET and self.overlap is not None:
|
||||
return queryset, Q(**{f'{prefix}overlap': self.overlap})
|
||||
if self.length is not strawberry.UNSET and self.length is not None:
|
||||
return queryset, Q(**{f'{prefix}len': self.length})
|
||||
return queryset, Q()
|
||||
|
||||
|
||||
@strawberry.input(one_of=True, description='Lookup for Array fields. Only one of the lookup fields can be set.')
|
||||
|
|
|
|||
|
|
@ -12,7 +12,17 @@ from strawberry.extensions import QueryDepthLimiter
|
|||
from strawberry.schema.config import StrawberryConfig
|
||||
|
||||
from dcim.choices import LocationStatusChoices
|
||||
from dcim.models import Device, DeviceRole, DeviceType, Location, Manufacturer, Site, VirtualChassis
|
||||
from dcim.models import (
|
||||
Device,
|
||||
DeviceRole,
|
||||
DeviceType,
|
||||
Location,
|
||||
Manufacturer,
|
||||
Rack,
|
||||
RackReservation,
|
||||
Site,
|
||||
VirtualChassis,
|
||||
)
|
||||
from extras.models import TableConfig, Tag
|
||||
from netbox.graphql.scalars import BigInt, BigIntScalar
|
||||
from netbox.graphql.schema import Query, get_schema_extensions, schema
|
||||
|
|
@ -315,6 +325,33 @@ class GraphQLAPITestCase(APITestCase):
|
|||
self.assertNotIn('errors', data)
|
||||
self.assertEqual(len(data['data']['device_list']), 3)
|
||||
|
||||
def test_graphql_array_length_lookup(self):
|
||||
"""
|
||||
The public GraphQL ``length`` array lookup must map to Django's ``len`` transform.
|
||||
Regression test for #22766 using a standard array field (RackReservation.units).
|
||||
"""
|
||||
self.add_permissions('dcim.view_rackreservation')
|
||||
url = reverse('graphql')
|
||||
|
||||
site = Site.objects.first()
|
||||
rack = Rack.objects.create(name='Reservation Rack', site=site)
|
||||
RackReservation.objects.create(rack=rack, units=[1, 2], user=self.user, description='Two units')
|
||||
RackReservation.objects.create(rack=rack, units=[3, 4, 5], user=self.user, description='Three units')
|
||||
|
||||
query = """
|
||||
{
|
||||
rack_reservation_list(filters: {units: {length: 2}}) {
|
||||
id units
|
||||
}
|
||||
}
|
||||
"""
|
||||
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']['rack_reservation_list']), 1)
|
||||
self.assertEqual(data['data']['rack_reservation_list'][0]['units'], [1, 2])
|
||||
|
||||
def test_graphql_tableconfig_object_type_exposes_id(self):
|
||||
"""TableConfigType.object_type must expose ContentType fields (e.g. id)."""
|
||||
self.add_permissions('extras.view_tableconfig')
|
||||
|
|
|
|||
Loading…
Reference in New Issue