【问题标题】:Graphene-Django nested filters (relay)Graphene-Django 嵌套过滤器(中继)
【发布时间】:2018-08-25 20:15:15
【问题描述】:

我正在尝试使用 graphene-django 的 DjangoFilterConnectionField 实现以下目标:

{
  allUsers(username_Icontains: "abc") {
    edges {
      node {
        id
        demographics (name_Icontains: "xyz") {
          id
          name
        }
      }
    }
  }
}

我知道在石墨烯 django 中,可以使用 graphene's List 进行嵌套过滤 但我不确定我是否可以使用DjangoFilterConnectionField 解决这个问题。

我有以下石墨烯(中继)架构:

class UserNode(DjangoObjectType):
    class Meta:
        model = User
        interfaces = (Node,)
        filter_fields = {
            'username': ['exact', 'icontains', 'in'],
        }

class DemographicNode(DjangoObjectType):
    class Meta:
        model = Demographic
        interfaces = (Node,)
        filter_fields = {
            'name': ['icontains'],
        }

 class Query(ObjectType):

    user = Node.Field(UserNode)
    all_users = DjangoFilterConnectionField(UserNode)

    demographic = Node.Field(DemographicNode)
    all_demographics = DjangoFilterConnectionField(DemographicNode)

docs 中建议在连接节点上也引入每个过滤器。所以它会是这样的:

class UserNode(DjangoObjectType):
    class Meta:
        model = User
        interfaces = (Node,)
        filter_fields = {
            'username': ['exact', 'icontains', 'in'],
            'demographic__name': ['icontains']
        }

但我认为必须有更好的方法来执行此操作,因为我必须为 20 多个嵌套节点执行此操作。

【问题讨论】:

  • 这远非理想,但也许您可以获取DemographicNode._meta.filter_fields 并将它们添加到UserNode(可能在UserNode__init__ 中),前置demographic__?跨度>
  • 是的,我想我最终还是会这样做。
  • 遇到和你一样的问题。我来自django rest framework(DRF),嵌套过滤使用django-filter开箱即用,我只需要在每个父子FilterSet元类上指定fields,根本不需要双下划线。但是graphene-django 似乎不支持这一点,因此您必须在父 FilterSet 中指定所有嵌套字段并在那里使用双下划线。忽略子 FilterSet 中的元信息这一事实可能会导致代码重复,尤其是当子 FilterSet 被多个父 FilterSet 重用时。

标签: python django graphql graphene-python


【解决方案1】:

我认为你在这两个模型之间有 OneToOneField,如果它是真的,你不能有这样的东西,因为它不合逻辑

想象一下,如果一个用户有一个 Demographic,并且您检索所有用户,那么对于每个用户,我们都有一个 Demographic,过滤一个 Demographic 是不合逻辑的。唯一的方法是用 UserNode 过滤它(正如你所说和所做的)

如果您有一个 ForeignKey 或 ManyToManyField 到用户模型,那么嵌套过滤就可以工作,然后您可以使用单独的过滤器在用户中检索它

我希望我已经能够让你明白了

【讨论】:

  • 谢谢,但这个例子也适用于 m2m 和 FK。显然石墨烯还没有这种能力。 (无论关系类型如何)
  • @morinx 我的代码中有 m2m 和 FK,我在其中做了嵌套过滤器!
  • 是的,您可以执行过滤,但结果并不完全符合您的预期。请参阅此问题以获取示例github.com/graphql-python/graphene-django/issues/410
猜你喜欢
  • 2017-03-15
  • 2021-10-13
  • 2021-11-09
  • 2019-02-26
  • 2018-05-17
  • 2018-02-24
  • 2023-03-11
  • 2021-06-21
  • 2020-05-19
相关资源
最近更新 更多