Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

graphene-django - How to filter?

I use graphen-django for build a GraphQL API. I have succesfully create this API, but I can't pass a argument for filter my response.

This is my models.py:

from django.db import models

class Application(models.Model):
    name = models.CharField("nom", unique=True, max_length=255)
    sonarQube_URL = models.CharField("Url SonarQube", max_length=255, blank=True, null=True)

    def __unicode__(self):
    return self.name

This is my schema.py: import graphene from graphene_django import DjangoObjectType from models import Application

class Applications(DjangoObjectType):
    class Meta:
        model = Application

class Query(graphene.ObjectType):
    applications = graphene.List(Applications)

    @graphene.resolve_only_args
    def resolve_applications(self):
        return Application.objects.all()


schema = graphene.Schema(query=Query)

My urls.py:

urlpatterns = [
    url(r'^', include(router.urls)),
    url(r'^admin/', admin.site.urls),
    url(r'^api-auth/', include('rest_framework.urls', namespace='rest_framework')),
    url(r'^api-token-auth/', authviews.obtain_auth_token),
    url(r'^graphql', GraphQLView.as_view(graphiql=True)),
]

As you can see, I also have a REST API.

My settings.py contains this:

GRAPHENE = {
    'SCHEMA': 'tibco.schema.schema'
}

I follow this: https://github.com/graphql-python/graphene-django

When I send this resquest:

{
  applications {
    name
  }
}

I've got this response:

{
  "data": {
    "applications": [
      {
        "name": "foo"
      },
      {
        "name": "bar"
      }
    ]
   }
}

So, it's works!

But when I try to pass an argument like this:

{
  applications(name: "foo") {
    name
    id
  }
}

I have this response:

{
  "errors": [
   {
      "message": "Unknown argument \"name\" on field \"applications\" of type \"Query\".",
      "locations": [
        {
          "column": 16,
          "line": 2
        }
      ]
    }
  ]
}

What i have missed? Or maybe I do something wrong?

like image 282
Neau Adrien Avatar asked Nov 02 '16 14:11

Neau Adrien


People also ask

What is Graphene in Django?

Graphene-Django provides some additional abstractions that make it easy to add GraphQL functionality to your Django project. First time? We recommend you start with the installation guide to get set up and the basic tutorial. It is worth reading the core graphene docs to familiarize yourself with the basic utilities.

Which package contains filter in Django?

Python Django filter contains The contains filter in Django returns all the objects that carry case-sensitive strings in the given field.

What is Relay in Graphene?

Relay is a Javascript framework built by Facebook with the purpose of improving the GraphQL architecture by making some core assumptions: A mechanism for refetching an object. A description of how to page through connections. Structure around mutations to make them predictable.


2 Answers

I've found a solution thanks to: https://docs.graphene-python.org/projects/django/en/latest/

This is my answer. I have edit my schema.py:

import graphene
from graphene import relay, AbstractType, ObjectType
from graphene_django import DjangoObjectType
from graphene_django.filter import DjangoFilterConnectionField
from models import Application

class ApplicationNode(DjangoObjectType):
    class Meta:
        model = Application
        filter_fields = ['name', 'sonarQube_URL']
        interfaces = (relay.Node, )

class Query(ObjectType):
    application = relay.Node.Field(ApplicationNode)
    all_applications = DjangoFilterConnectionField(ApplicationNode)

schema = graphene.Schema(query=Query)

Then, it was missing a package: django-filter (https://github.com/carltongibson/django-filter/tree/master). Django-filter is used by DjangoFilterConnectionField.

Now I can do this:

query {
  allApplications(name: "Foo") {
    edges {
      node {
        name
      }
    }
  }
}

and the response will be:

{
  "data": {
    "allApplications": {
      "edges": [
        {
          "node": {
            "name": "Foo"
          }
        }
      ]
    }
  }
}
like image 140
Neau Adrien Avatar answered Oct 14 '22 22:10

Neau Adrien


If you're in my case and don't want to use Relay, you can also handle filtering directly in you resolvers using Django orm filtering. Example here: Filter graphql query in django

like image 33
elachere Avatar answered Oct 14 '22 22:10

elachere