Graphene Django is an easy to use library for writing GraphQL APIs within Django. But some of the documentation for Graphene is less than great.
When I was learning Graphene Django, I originally found it very hard to expose an @property
value of my model to the GraphQL API. This article will look into how to do that, and also why it works.
Say you have a Poll object, and you added a URL property:
class Poll(models.Model):
...
@property
def url(self):
return 'https://pollsite/polls/' + id
Then you can simply add a line to specify its existence in the schema:
class PollType(DjangoObjectType):
class Meta:
model = models.Poll
interfaces = (relay.Node,)
# This is it, so simple and so functional:
url = graphene.String()
That's it. Just use the form property_name = graphene.DataType()
. You can even use more fancy datatypes, like a graphene.List(graphene.Int())
. There is a good reference to check it out.
First, we need to understand the resolver of the property. By default, the resolvers perform a getattr
lookup on the object. This means it would like be this if we were to write it manually:
url = graphene.String()
def resolve_url(self, args, context, info):
return self.url
But that code looks stupid! Isn't the url attribute the graphene.String()
? Isn't that code broken?
Well the self
in a resolver doesn't represent an instance of the class. Or maybe it does. Anyway; Graphene is a festival of metaclass programming. So the self
object is really the Django object, not your graphene object! Once I found that out, it all started to make a lot more sense to me.
Well, that's a very quick dive into the weird and wonderful world of the Graphene framework. Metaclass magic hey!
If you enjoy these random Graphene tips, make sure to subscribe below.
Comments, thoughts? Mail them to sam@sam.today. I would love to hear them!