当过滤器字符串为空时,如何停止 Graphql + Django-Filters 到 return 所有对象?

How to stop Graphql + Django-Filters to return All Objects when Filter String is Empty?

使用:


我有一个简单的 Birds Django 模型,其字段如 namehabitat 并在这些字段上应用了不同的过滤器,例如 icontainsiexact。我的目标是在我的前端 (Vue) 中应用一个简单的搜索字段。到目前为止它是有效的,但是只要这个过滤器值是空的或有空白 (参见示例 3),Graphql return 就是所有对象。

我的第一个方法是在 FrontEnd 上对我的输入值使用某种逻辑,比如当 String 是 Empty/blank 发送 isnull=true 时。但后来我认为 Django 应该首先处理这个问题。 我想这个问题与我的 filters (参见 Django < relay_schema.py) 或者换句话说我必须在这些过滤器上应用某种逻辑?

此刻我尝试自定义一些 filterset_class 但感觉这可能太多了,也许我错过了什么?所以我在这里问是否有人有一些提示,因此我的问题是:

当过滤器字符串为空时,如何停止 Graphql + Django 过滤器到 return 所有对象?

GraphiQL IDE

Example 1


query {birdsNodeFilter (name_Iexact: "finch") {
  edges {
    node {
      id
      name
    }
     }
    }
}

Returns

{
  "data": {
    "birdsNodeFilter": {
      "edges": [
        {
          "node": {
            "id": "QmlyZHNOb2RlOjE=",
            "name": "Finch",
            "habitat": "Europe"
          }
        }
      ]
    }
  }
}

适合我!

Example 2


query {birdsNodeFilter (name_Iexact: "Unicorns") {
  edges {
    node {
      id
      name
      habitat
    }
     }
    }
}

Returns

{
  "data": {
    "birdsNodeFilter": {
      "edges": []
    }
  }
}

那里没有独角兽 - 很好

Example 3


query {birdsNodeFilter (name_Iexact: "") {
  edges {
    node {
      id
      name
    }
     }
    }
}

Return

{
  "data": {
    "birdsNodeFilter": {
      "edges": [
        {
          "node": {
            "id": "QmlyZHNOb2RlOjE=",
            "name": "Finch",
            "habitat": "Europe"
          }
        },
        {
          "node": {
            "id": "QmlyZHNOb2RlOjI=",
            "name": "Bald Eagle",
            "habitat": "USA"
          }
        },

<...And so on...>

不适合我!

Django

relay_schema.py


class BirdsNode(DjangoObjectType):
    class Meta:
        model = Birds
        filter_fields = {
            'id': ['iexact'],
            'name': ['iexact', 'icontains', 'istartswith', 'isnull'],
            'habitat': ['iexact', 'icontains', 'istartswith'],
        }
        interfaces = (relay.Node, )


class BirdQuery(graphene.ObjectType):
    birdConNode = relay.Node.Field(BirdsNode)
    birdsNodeFilter = DjangoFilterConnectionField(BirdsNode) 

这是我在 GraphiQL 和我的前端 VUE 中工作的解决方案。 我为每个 Filter 添加了一个逻辑到 Birds2Querydef resolve_all_birds2 (出于测试目的而不是在所有 Filter 上)。 除此之外,我还添加了一个 ExtendedConnection 用于计数。

注意: 我更改了我之前问题中的 class 名称。

更新:此解决方案适用于 python 方面。但是 apollo client 还提供了 Apollo manager - 也称为 Dollar Apollo - 您还可以使用 this.$apollo.queries.tags.skip 属性 作为静态或动态解决方案来启动和停止查询。

relay_schema.py

class ExtendedConnection(Connection):
    class Meta:
        abstract = True

    total_count = Int()
    edge_count = Int()
    name_check = ""

    def resolve_total_count(root, info, **kwargs):
        return root.length
    def resolve_edge_count(root, info, **kwargs):
        return len(root.edges)

class Birds2Node(DjangoObjectType):
    class Meta:

        model = Birds
        filter_fields =  {
            'id':  ['exact', 'icontains'],
            'name': ['exact', 'icontains', 'istartswith', 'iendswith'],
        }

        interfaces = (relay.Node, )
        connection_class = ExtendedConnection

class Birds2Query(ObjectType):
    birds2 = relay.Node.Field(Birds2Node)
    all_birds2 = DjangoFilterConnectionField(Birds2Node)


    def resolve_all_birds2(self, info, **kwargs):
        # Filtering for Empty/ Blank Values in Filter.Key.Value before returning queryset
         if 'name__icontains' in kwargs:
            nameIcon = kwargs['name__icontains']
            nameIconBool = bool(nameIcon.strip()) # if blanks turns False           
            if nameIconBool == False: # has blanks         
                return Birds.objects.filter(name=None)
            pass

    
        if 'name__istartswith' in kwargs:           
            nameIsta = kwargs['name__istartswith']
            nameIstaBool = bool(nameIsta.strip()) # if blanks turns False          
            if nameIstaBool == False: # has blanks         
                return Birds.objects.filter(name=None)
            pass
         return

GraphiQL Blockquote

示例 1

query {allBirds2 (name_Icontains:""){
  totalCount
    edgeCount
    edges {
      node {
        id
        name
        habitat
      }  
    }
  }
}

过滤器为空时停止 return 所有对象。

{
  "data": {
    "allBirds2": {
      "totalCount": 0,
      "edgeCount": 0,
      "edges": []
    }
  }
}

示例 2 有空格和一个字母

query {allBirds2 (name_Icontains:" f  "){
  totalCount
    edgeCount
    edges {
      node {
        id
        name
        habitat
      }  
    }
  }
}

return - 正是我想要的

{
  "data": {
    "allBirds2": {
      "totalCount": 1,
      "edgeCount": 1,
      "edges": [
        {
          "node": {
            "id": "QmlyZHMyTm9kZTox",
            "name": "Finch",
            "habitat": "Europe"
          }
        }
      ]
    }
  }
}