如何解决如何编写将使用`django-filters`在整数字段上使用范围过滤器的GraphQL查询? 参考
我在GraphQL API中使用graphene-python
,django-filters
和relay
。假设我有一个类型为FrameType
的类型,该类型具有一个整数字段time_offset
,并且我希望能够在其上使用 range -仅询问具有{ {1}}在给定范围内。我根据graphene-python docs用自定义time_offset
准备了schema.py
:
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"
?
解决方法
遗憾的是,这是不可能的。但是,有一种解决方法
将过滤器类别调整为
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
}
}
}
参考
- 使用
Filter.method
--(django-filter
doc)自定义过滤结果
您可以在Django的查询集级别处理 range 选项,而不会干扰现有的中继查询。
就您而言,
- 将
start_time_offset
和end_time_offset
参数传递给DjangoConnectionField
- 覆盖
resolve_frames
- 如果用户提供了
start_time_offset
或end_time_offset
,则对Django查询集进行过滤,否则返回objects.all()
class Query(ObjectType):
frames = filter.DjangoFilterConnectionField(FrameType,start_time_offset=graphene.Int(),end_time_offset=graphene.Int())
def resolve_scans(self,info,start_time_offset=None,end_time_offset=None,**kwargs):
if start_time_offset and end_time_offset:
return Frame.objects.filter(time_offset__range=(start_time_offset,end_time_offset))
elif start_time_offset:
return Frame.objects.filter(time_offset__gte=start_time_offset)
elif end_time_offset:
return Frame.objects.filter(time_offset__lte=end_time_offset)
return Frame.objects.all()
现在,您可以使用中继提供的常规过滤器对其进行查询:
query Frame {
frames(last: 5,startTimeOffset: 4350,endTimeOffset:5000) {
edges {
node {
timeOffset
}
}
}
,
它有点旧,但因为它可能对其他人有帮助,您可以检查这个 thread,它使用 django filterset for DateRangeFiled,我认为您可以使用 filterset RangeFilter 对整数使用类似的方法。另请查看 this 以了解有关石墨烯过滤器集的更多信息。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。