首页 > 解决方案 > 如何使用`django-filters`编写将在整数字段上使用范围过滤器的GraphQL查询?

问题描述

我正在使用graphene-python,django-filtersrelay在我的 GraphQL API 中。假设我有一个FrameType具有整数字段的类型,time_offset并且我希望能够在其上使用范围- 仅询问​​具有time_offset给定范围内的帧。我schema.py根据graphene-python 文档准备了我的自定义FilterSet

import django_filters
from graphene import ObjectType, relay
from graphene_django import DjangoObjectType, filter
from my_app.blabla import models



class FrameFilter(django_filters.FilterSet):
    time_offset = django_filters.RangeFilter()

    class Meta:
        model = models.Frame
        fields = ("time_offset",)


class FrameType(DjangoObjectType):
    class Meta:
        model = models.Frame
        filterset_class = FrameFilter
        interfaces = (relay.Node,)


class Query(ObjectType):
    frames = filter.DjangoFilterConnectionField(FrameType)

    class Meta:
        abstract = True

但是,我现在不知道如何查询该timeOffset字段。我在网上找不到该django_filters.RangeFilter领域的示例。这是我尝试过的一个查询:

query Frame {
  frames(first: 20, timeOffset: "{\"gt\":\"4350\", \"lt\":\"5000\"}") {
    edges {
      node {
        timeOffset
    }
  }
}

......还有这些替代品:

timeOffset: "{\"gt\":4350, \"lt\":5000}"
timeOffset: "{\"start\":\"4350\", \"end\":\"5000\"}"
timeOffset: "{\"min\":\"4350\", \"max\": \"4500\"}"
timeOffset: "[\"4350\", \"5000\"]"
timeOffset: "[4350, 5000]"
timeOffset: "[4350]"
timeOffset: "4350,5000"

这些查询不会引发任何错误,但它们也不会过滤(返回所有结果)。我迷路了,我不确定我是否还没有找到正确的语法,或者我的后端代码中可能有一些错误。我应该如何使用和查询django_filters.RangeFilter字段?

标签: pythongraphqlgraphene-pythondjango-filters

解决方案


可悲的是,这是不可能的。但是,有一个解决方法

将您的过滤器类调整为

def custom_range_filter_method(queryset, field_name, value):
    if value:
        queryset = queryset.filter(**{f'{field_name}__range': value.split(',')})
    return queryset


class FrameFilter(django_filters.FilterSet):
    time_offset = filters.Filter(method=custom_range_filter_method)

    class Meta:
        model = models.Frame
        fields = ("time_offset",)

现在查询架构

query Frame {
  frames(first: 20, timeOffset: "4350,5000") {
    edges {
      node {
        timeOffset
    }
  }
}

参考


推荐阅读