首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何使用graphene-django在GraphQL中根据in列表过滤查询?

如何使用graphene-django在GraphQL中根据in列表过滤查询?
EN

Stack Overflow用户
提问于 2019-01-16 21:49:31
回答 5查看 4.3K关注 0票数 7

我正在尝试使用Django和Graphene执行一个GraphQL查询。为了使用id查询一个单独的对象,我执行了以下操作:

代码语言:javascript
复制
{
  samples(id:"U2FtcGxlU2V0VHlwZToxMjYw") {
    edges {
      nodes {
        name
      }
    }
  }
}

而且它工作得很好。当我尝试使用多个id进行查询时,会出现问题,如下所示:

代码语言:javascript
复制
{
  samples(id_In:"U2FtcGxlU2V0VHlwZToxMjYw, U2FtcGxlU2V0VHlwZToxMjYx") {
    edges {
      nodes {
        name
      }
    }
  }
} 

在后一种情况下,我得到以下错误:

代码语言:javascript
复制
argument should be a bytes-like object or ASCII string, not 'list'

这是如何在django-graphene中定义类型和查询的草图

代码语言:javascript
复制
class SampleType(DjangoObjectType):
  class Meta:
    model = Sample
    filter_fields = {
      'id': ['exact', 'in'],
     }
     interfaces = (graphene.relay.Node,)

class Query(object):
  samples = DjangoFilterConnectionField(SampleType)

  def resolve_sample_sets(self, info, **kwargs):
    return Sample.objects.all()
EN

回答 5

Stack Overflow用户

发布于 2020-03-21 13:11:17

来自django-graphene的GlobalIDMultipleChoiceFilter解决了这个问题,如果你在字段名中加上" in“。您可以像这样创建过滤器

代码语言:javascript
复制
from django_filters import FilterSet
from graphene_django.filter import GlobalIDMultipleChoiceFilter

class BookFilter(FilterSet):
    author = GlobalIDMultipleChoiceFilter()

并通过以下方式使用它

代码语言:javascript
复制
{
  books(author: ["<GlobalID1>", "<GlobalID2>"]) {
    edges {
      nodes {
        name
      }
    }
  }
}

仍然不完美,但对自定义代码的需求已降至最低。

票数 5
EN

Stack Overflow用户

发布于 2019-08-14 06:53:19

我在实现“in”过滤器时也遇到了问题--它现在似乎在graphene-django中实现了错误,并且没有像预期的那样工作。以下是使其工作的步骤:

  1. 从您的filter_fields
  2. Add中删除' in‘筛选器,并将名为'id__in’的输入值添加到您的DjangoFilterConnectionField中,并使其成为in列表
  3. 重命名您的冲突解决程序以匹配'samples‘字段。
  4. 在您的冲突解决程序中处理针对该字段的'id__in’筛选。对于您来说,这将如下所示:

代码语言:javascript
复制
from base64 import b64decode

def get_pk_from_node_id(node_id: str):
    """Gets pk from node_id"""
    model_with_pk = b64decode(node_id).decode('utf-8')
    model_name, pk = model_with_pk.split(":")
    return pk


class SampleType(DjangoObjectType):
    class Meta:
        model = Sample
        filter_fields = {
            'id': ['exact'],
         }
        interfaces = (graphene.relay.Node,)


class Query(object):

    samples = DjangoFilterConnectionField(SampleType, id__in=graphene.List(graphene.ID))

    def resolve_samples(self, info, **kwargs):
        # filter_field for 'in' seems to not work, this hack works
        id__in = kwargs.get('id__in')
        if id__in:
            node_ids = kwargs.pop('id__in')
            pk_list = [get_pk_from_node_id(node_id) for node_id in node_ids]
            return Sample._default_manager.filter(id__in=pk_list)
        return Sample._default_manager.all()

这将允许您使用以下api调用过滤器。注意在签名中使用实际的数组(我认为这是一个比发送逗号分隔的值字符串更好的API )。这个解决方案仍然允许您将其他过滤器添加到请求中,并且它们将正确地链接在一起。

代码语言:javascript
复制
{
  samples(id_In: ["U2FtcGxlU2V0VHlwZToxMjYw", "U2FtcGxlU2V0VHlwZToxMjYx"]) {
    edges {
      nodes {
        name
      }
    }
  }
} 
票数 1
EN

Stack Overflow用户

发布于 2020-05-03 11:58:35

您可以很容易地使用过滤器,只需将其与您的节点放在一起即可。

代码语言:javascript
复制
class ReportFileFilter(FilterSet):
    id = GlobalIDMultipleChoiceFilter()

然后在您的查询中使用-

代码语言:javascript
复制
class Query(graphene.ObjectType):
    all_report_files = DjangoFilterConnectionField(ReportFileNode, filterset_class=ReportFileFilter)

这是graphql django的中继实现。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/54218505

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档