Graphene/Django (GraphQL):如何使用查询参数来排除与特定过滤器匹配的节点?

Posted

技术标签:

【中文标题】Graphene/Django (GraphQL):如何使用查询参数来排除与特定过滤器匹配的节点?【英文标题】:Graphene/Django (GraphQL): How to use a query argument in order to exclude nodes matching a specific filter? 【发布时间】:2017-02-06 17:43:30 【问题描述】:

我在Django/Graphene 后端设置中有一些视频项目。每个视频项目都链接到一个所有者。 在 React 应用程序中,我想通过 GraphQL 一方面查询当前用户拥有的所有视频,另一方面查询当前用户不拥有的所有视频。

我可以在客户端运行以下GraphQl 查询和过滤器:

query AllScenes 
  allScenes 
    edges 
      node 
        id,
        name,
        owner 
          name
        
      
    
  

我宁愿有两个带有过滤器参数的查询,直接向我的后端询问相关数据。比如:

query AllScenes($ownerName : String!, $exclude: Boolean!) 
  allScenes(owner__name: $ownerName, exclude: $exclude) 
    edges 
      node 
        id,
        name,
        owner 
          name
        
      
    
  

我会使用ownerName = currentUserNameexclude = True/False 进行查询,但我无法在后端检索我的exclude 参数。这是我在 schema.py 文件中尝试过的代码:

from project.scene_manager.models import Scene

from graphene import ObjectType, relay, Int, String, Field, Boolean, Float

from graphene.contrib.django.filter import DjangoFilterConnectionField
from graphene.contrib.django.types import DjangoNode

from django_filters import FilterSet, CharFilter





class SceneNode(DjangoNode):

    class Meta:

        model = Scene





class SceneFilter(FilterSet):

    owner__name = CharFilter(lookup_type='exact', exclude=exclude)


    class Meta:

        model = Scene

        fields = ['owner__name']


    
class Query(ObjectType):


    scene = relay.NodeField(SceneNode)

    all_scenes = DjangoFilterConnectionField(SceneNode, filterset_class=SceneFilter, exclude=Boolean())



    def resolve_exclude(self, args, info):

        exclude = args.get('exclude')

        return exclude




    class Meta:

        abstract = True

使用了我的自定义 SceneFilter,但我不知道如何将 exclude arg 传递给它。 (我认为我没有正确使用resolver)。对此问题的任何帮助将不胜感激!

【问题讨论】:

【参考方案1】:

切换到graphene-django 1.0,我已经能够使用以下查询定义做我想做的事:

class Query(AbstractType):

    selected_scenes = DjangoFilterConnectionField(SceneNode, exclude=Boolean())

    def resolve_selected_scenes(self, args, context, info):
        owner__name = args.get('owner__name')
        exclude = args.get('exclude')
        if exclude:
            selected_scenes = Scene.objects.exclude(owner__name=owner__name)
        else:
            selected_scenes = Scene.objects.filter(owner__name=owner__name)
        return selected_scenes

BossGrand 在 GitHub 上提出an other solution

【讨论】:

以上是关于Graphene/Django (GraphQL):如何使用查询参数来排除与特定过滤器匹配的节点?的主要内容,如果未能解决你的问题,请参考以下文章

在 graphene/graphene_django 中扩展查询参数

Graphene Django 查询 Elasticsearch

在 Graphene Django 中查询多个模型

如何使用`django-filters`编写将在整数字段上使用范围过滤器的GraphQL查询?

如何根据 Graphene/Django 上的用户类型限制模型上的字段访问?

如何使用 curl 登录 Graphene Django 应用程序?