Как использовать MultipleChoiceFilter в graphene-django?

#django #graphql #django-filter #relay #graphene-django

#django #graphql #django-фильтр #реле #graphene-django

Вопрос:

У меня есть приложение Django с конечной точкой graphql. Мне нужна возможность фильтровать объекты сразу по нескольким значениям определенного поля.

У меня есть следующая схема графена:

 class ChannelFilter(FilterSet):
    type = MultipleChoiceFilter(choices=Channel.TYPES)

    class Meta:
        model = Channel
        fields = ['type']


class ChannelNode(DjangoObjectType):

    class Meta:
        model = Channel
        filter_fields = ['type']
        interfaces = (relay.Node,)


class Query(graphene.ObjectType):
    channels = DjangoFilterConnectionField(
        ChannelNode, filterset_class=ChannelFilter
    )


schema = graphene.Schema(query=Query)

  

Затем я попробовал следующие запросы graphql для фильтрации моих объектов:

 query {
  channels(type: "BOT") {
    edges {
      node {
        id
      }
    }
  }
}

  

В результате появляется следующая ошибка:

 {
  "errors": [
    {
      "message": "['{"type": [{"message": "Enter a list of values.", "code": "invalid_list"}]}']",
      "locations": [
        {
          "line": 2,
          "column": 3
        }
      ],
      "path": [
        "channels"
      ]
    }
  ],
  "data": {
    "channels": null
  }
}
  
 query {
  channels(type: ["BOT"]) {
    edges {
      node {
        id
      }
    }
  }
}

  

В результате появляется следующая ошибка:

 
{
  "errors": [
    {
      "message": "Argument "type" has invalid value ["BOT"].nExpected type "String", found ["BOT"].",
      "locations": [
        {
          "line": 2,
          "column": 18
        }
      ]
    }
  ]
}

  

Как правильно использовать MultipleChoiceFilter? Спасибо

Ответ №1:

Возможно, вам потребуется зарегистрировать конвертер полей формы как

 import graphene
from graphene_django.forms.converter import convert_form_field
from django_filters.fields import MultipleChoiceField


@convert_form_field.register(MultipleChoiceField)
def convert_multiple_choice_filter_to_list_field(field):
    return graphene.List(graphene.String, required=field.required)  

Затем используйте channels(type: ["BOT"]) нотацию для фильтрации.

Важное замечание

Вы можете поместить фрагмент кода register в любом месте, но убедитесь, что он выполняется при запуске сервера.