Как остановить Graphql + Django -Filters, чтобы вернуть все объекты, когда строка фильтра пуста? - PullRequest
1 голос
/ 31 января 2020

Использование:

  • Django 3.x [Django -фильтры 2.2.0, графен- django 2.8.0, graphql-relay 2.0.1]
  • Vue 2.x [Vue -Apollo]

У меня есть простая Birds Django -модель с полями типа name, habitat и применил к этим полям различные фильтры, такие как icontains или iexact. Моей целью было применить простое поле поиска в моем интерфейсе (Vue). Пока это работает, но всякий раз, когда это значение фильтра пусто или имеет пробелы (см. Пример 3) , Graphql возвращает все объекты.

Мой первый подход был на FrontEnd и использовать какую-то логику c для моего входного значения, например, когда String равен Empty / blank send isnull=true. Но потом я подумал, что Django должен справиться с этим в первую очередь. Я предполагаю, что эта проблема связана с моими filters (см. Django или другими словами, нужно ли мне применять какие-то логи c к этим Фильтры?

В данный момент я пытаюсь настроить некоторые filterset_class, но кажется, что это может быть слишком много, может быть, я что-то упустил? Поэтому я спрашиваю здесь, может быть, у кого-то есть какие-то подсказки, поэтому мой вопрос:

Как остановить Graphql + Django -Filters для возврата всех объектов, когда строка фильтра пуста?

GraphiQL IDE

Пример 1


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

Возвраты

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

Отлично для меня!

Пример 2


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

Возвращает

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

Там нет единорогов - хорошо

Пример 3


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

Возврат

{
  "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) 

1 Ответ

1 голос
/ 03 февраля 2020

Это мое решение, которое работало в GraphiQL и в моем Frontend VUE. Я добавил лог c к Birds2Query с def resolve_all_birds2 для каждого фильтра (для целей тестирования не для всех фильтров). Кроме того, я также добавил ExtendedConnection для подсчета.

Примечание: я изменил имена классов из моего предыдущего вопроса.

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 Цитата

Пример 1

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

Остановлен, чтобы вернуть все объекты, когда фильтр пуст.

{
  "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"
          }
        }
      ]
    }
  }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...