diff --git a/netbox/netbox/graphql/filter_lookups.py b/netbox/netbox/graphql/filter_lookups.py index 583caa6d3..243dfb4e8 100644 --- a/netbox/netbox/graphql/filter_lookups.py +++ b/netbox/netbox/graphql/filter_lookups.py @@ -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: