【问题标题】:Graphene/Django (GraphQL): How to use a query argument in order to exclude nodes matching a specific filter?Graphene/Django (GraphQL):如何使用查询参数来排除与特定过滤器匹配的节点?
【发布时间】: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 = currentUserName 和exclude = 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)。对此问题的任何帮助将不胜感激!

【问题讨论】:

    标签: python django graphql graphene-python


    【解决方案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

    【讨论】:

      猜你喜欢
      • 2019-06-10
      • 2021-10-31
      • 2019-02-26
      • 2023-03-11
      • 1970-01-01
      • 1970-01-01
      • 2017-03-15
      • 2011-01-26
      • 2012-10-05
      相关资源
      最近更新 更多