Closes #22059: Consolidate numeric GraphQL lookup classes via shared mixin

Extract _NumericLookupMixin with shared get_filter() and filter() methods.
IntegerLookup, BigIntegerLookup, and FloatLookup each inherit from it and
declare only their type-specific fields, eliminating triplicated logic.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Brian Tiemann 2026-05-19 11:53:11 -04:00 committed by Jeremy Stretch
parent d25e2d43d0
commit 31338a28e3
1 changed files with 26 additions and 60 deletions

View File

@ -59,83 +59,49 @@ class JSONLookup:
return None
class _NumericLookupMixin:
"""Shared filter logic for numeric lookup input types (Integer, BigInteger, Float)."""
def get_filter(self):
for field in self.__strawberry_definition__.fields:
value = getattr(self, field.name, None)
if value is not strawberry.UNSET:
return value
return None
@strawberry_django.filter_field
def filter(self, info: Info, queryset: QuerySet, prefix: DirectiveValue[str] = '') -> tuple[QuerySet, Q]:
filters = self.get_filter()
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)
@strawberry.input(one_of=True, description='Lookup for Integer fields. Only one of the lookup fields can be set.')
class IntegerLookup:
class IntegerLookup(_NumericLookupMixin):
filter_lookup: FilterLookup[int] | None = strawberry_django.filter_field()
range_lookup: RangeLookup[int] | None = strawberry_django.filter_field()
comparison_lookup: ComparisonFilterLookup[int] | None = strawberry_django.filter_field()
def get_filter(self):
for field in self.__strawberry_definition__.fields:
value = getattr(self, field.name, None)
if value is not strawberry.UNSET:
return value
return None
@strawberry_django.filter_field
def filter(self, info: Info, queryset: QuerySet, prefix: DirectiveValue[str] = '') -> tuple[QuerySet, Q]:
filters = self.get_filter()
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)
@strawberry.input(one_of=True, description='Lookup for BigInteger fields. Only one of the lookup fields can be set.')
class BigIntegerLookup:
class BigIntegerLookup(_NumericLookupMixin):
filter_lookup: FilterLookup[BigInt] | None = strawberry_django.filter_field()
range_lookup: RangeLookup[BigInt] | None = strawberry_django.filter_field()
comparison_lookup: ComparisonFilterLookup[BigInt] | None = strawberry_django.filter_field()
def get_filter(self):
for field in self.__strawberry_definition__.fields:
value = getattr(self, field.name, None)
if value is not strawberry.UNSET:
return value
return None
@strawberry_django.filter_field
def filter(self, info: Info, queryset: QuerySet, prefix: DirectiveValue[str] = '') -> tuple[QuerySet, Q]:
filters = self.get_filter()
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)
@strawberry.input(one_of=True, description='Lookup for Float fields. Only one of the lookup fields can be set.')
class FloatLookup:
class FloatLookup(_NumericLookupMixin):
filter_lookup: FilterLookup[float] | None = strawberry_django.filter_field()
range_lookup: RangeLookup[float] | None = strawberry_django.filter_field()
comparison_lookup: ComparisonFilterLookup[float] | None = strawberry_django.filter_field()
def get_filter(self):
for field in self.__strawberry_definition__.fields:
value = getattr(self, field.name, None)
if value is not strawberry.UNSET:
return value
return None
@strawberry_django.filter_field
def filter(self, info: Info, queryset: QuerySet, prefix: DirectiveValue[str] = '') -> tuple[QuerySet, Q]:
filters = self.get_filter()
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)
@strawberry.input
class JSONFilter: