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

Graphene/Django (GraphQL): How to use a query argument in order to exclude nodes matching a specific filter?

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

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

1
2
3
4
5
6
7
8
9
10
11
12
13
query AllScenes {
  allScenes {
    edges {
      node {
        id,
        name,
        owner {
          name
        }
      }
    }
  }
}

我希望有两个带有过滤器参数的查询,直接向我的后端询问相关数据。类似于:

1
2
3
4
5
6
7
8
9
10
11
12
13
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文件中尝试过的代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
from project.scene_manager.models import Scenea۬
from graphene import ObjectType, relay, Int, String, Field, Boolean, Floata۬
from graphene.contrib.django.filter import DjangoFilterConnectionField
from graphene.contrib.django.types import DjangoNodea۬
from django_filters import FilterSet, CharFilter
a۬a۬a۬

class SceneNode(DjangoNode):
a€¨    class Meta:a€¨
        model = Scene


a۬a۬a۬class SceneFilter(FilterSet):a۬
    owner__name = CharFilter(lookup_type='exact', exclude=exclude)
a۬
    class Meta:a€¨
        model = Scenea€¨
        fields = ['owner__name']a€¨a€¨
   
class Query(ObjectType):a۬a۬
    scene = relay.NodeField(SceneNode)a€¨
    all_scenes = DjangoFilterConnectionField(SceneNode, filterset_class=SceneFilter, exclude=Boolean())a€¨a€¨

    def resolve_exclude(self, args, info):a€¨
        exclude = args.get('exclude')a€¨
        return excludea€¨a€¨a€¨

    class Meta:a€¨
        abstract = True

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


切换到graphene-django 1.0,我已经可以使用以下查询定义执行所需的操作:

1
2
3
4
5
6
7
8
9
10
11
12
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上提出了另一种解决方案