Alexander Fedotov
Alexander Fedotov

Reputation: 1085

How to use MultipleChoiceFilter in graphene-django?

I have an Django application with graphql endpoint. I need the ability to filter objects at once by several values of a certain field.

I have the following graphene Scheme:

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)

Then i tried the following graphql queries to filter my objects:

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

As a result, the following error:

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

As a result, the following error:


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

How to use MultipleChoiceFilter correctly? Thanks

Upvotes: 3

Views: 837

Answers (1)

JPG
JPG

Reputation: 88659

You may need to register the form field converter as

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)

Then use channels(type: ["BOT"]) notation to filter.

Important Note

You can put the register code snippet anywhere, but, make sure it is getting executed at the server startup.

Upvotes: 3

Related Questions