Как интегрировать пользовательский входной аргумент в набор запросов Graphene DjangoFilterConnectionField?
Мне интересно, какой самый чистый способ интегрировать пользовательский входной аргумент Graphene DjangoFilterConnectionField в набор запросов по умолчанию?
Я повторяю следующий класс Graphene Query, пользовательский входной атрибут которого пытается интегрировать функцию PgVector CosineDistance :
class Query(graphene.ObjectType):
all_the_small_things = DjangoFilterConnectionField(
VectorNode,
embedding=graphene.List(graphene.Float),
)
def resolve_all_the_small_things(
root,
info,
**kwargs,
):
from pgvector.django import CosineDistance
annotations = {}
if kwargs.get("embedding"):
annotations["embedding"] = CosineDistance(
"embedding", kwargs.pop("embedding")
)
if annotations:
# How best to integrate this into the existing behavior?
# VectorNode.objects.annotate(**annotations)
# now use filter functionality provided by
# the default resolver.
Я хотел бы расширить поведение запроса по умолчанию (т. е. фильтрацию), если предоставлен пользовательский ввод, и использовать поведение по умолчанию как есть, если это не так. Нужно ли мне реализовать свой собственный набор запросов и/или набор фильтров? Есть ли способ отразить/изменить поведение по умолчанию, используя аргументы функции?
Примечание. Я думаю, что долгосрочным ответом на этот вопрос будет добавление поддержки столбцов PG Vector в Graphene и/или создание подкласса фильтров django-filters, но мне действительно нужно понять, как все это сочетается, прежде чем серьезно думать о том, как подойти к любому из что вверх по течению.
1 ответ
Чтобы интегрировать пользовательский входной аргумент в набор запросов по умолчанию Graphene DjangoFilterConnectionField:
Создайте собственный набор фильтров
Переопределить
get_queryset
метод:from django_filters import FilterSet, filters from graphene_django.filter import DjangoFilterConnectionField class VectorFilterSet(FilterSet): cosine_distance = filters.Float() # Define your custom input argument here class Meta: model = VectorNode fields = [] # Specify other fields for filtering if needed class Query(graphene.ObjectType): all_the_small_things = DjangoFilterConnectionField( VectorNode, filterset_class=VectorFilterSet, # Use your custom FilterSet cosine_distance=graphene.Float(), # Add the custom input argument to the Query field ) def resolve_all_the_small_things( root, info, **kwargs, ): from pgvector.django import CosineDistance queryset = VectorNode.objects.all() cosine_distance = kwargs.pop("cosine_distance", None) if cosine_distance is not None: queryset = queryset.annotate( cosine_distance=CosineDistance("embedding", cosine_distance) ) return queryset
Если ваши требования становятся более сложными или вам нужен более детальный контроль над поведением фильтрации, вы можете рассмотреть возможность реализации собственного преобразователя или создания собственного поля подключения, которое расширяет DjangoFilterConnectionField.