Graphene-Django 嵌套过滤器(中继)

Posted

技术标签:

【中文标题】Graphene-Django 嵌套过滤器(中继)【英文标题】:Graphene-Django nested filters (relay) 【发布时间】: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 重用时。 【参考方案1】:

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

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

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

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

【讨论】:

谢谢,但这个例子也适用于 m2m 和 FK。显然石墨烯还没有这种能力。 (无论关系类型如何) @morinx 我的代码中有 m2m 和 FK,我在其中做了嵌套过滤器! 是的,您可以执行过滤,但结果并不完全符合您的预期。请参阅此问题以获取示例github.com/graphql-python/graphene-django/issues/410

以上是关于Graphene-Django 嵌套过滤器(中继)的主要内容,如果未能解决你的问题,请参考以下文章

在没有中继的情况下使用带有graphene-django的子字段中的参数进行分页

如何在graphene-django中使用MultipleChoiceFilter?

如何更改graphene-python(中继)中的连接参数(之后,之前)?

中继现代嵌套分页

DataTable 打破了嵌套中继器和引导程序

嵌套片段数据在中继中始终相同