Using GraphQL with Django
Before we dive into using GraphQL with Django, let us briefly introduce both these technologies. Django is a Python-based web framework that can be used to create websites or web applications rapidly. GraphQL is a query language for API’s and server-side runtime that allow us to retrieve or alter data from the server, much like REST or SOAP. GraphQL has a strongly typed schema.
The main advantage of GraphQL over REST is that there in GraphQL there can only be a single endpoint for the API to fetch different requests instead of making different endpoints for those requesting a different REST type service. Also, another major advantage is flexibility in the data structure of the API, only the required data can be fetched, instead of the rigid structure of the REST API where there can be over fetching or under fetching (n+1 problem). Due to these features, the integration of frontend to the backend is much easier and faster using GraphQL compared to REST.
I’ll not be discussing the whole schema of GraphQL in this blog, but you can learn more about it here. Now let us look at Graphene. It is a library that is used to implement GraphQL API in Python much like Apollo or Ariadne.
Let us install graphene using pip in a Django project. I’d recommend creating a virtual environment first.
pip3 install graphene_django
Now create a project of your choice, eg -
django-admin.py startproject todo .
Start the app and make migrations -
django-admin.py startapp todo
cd ..
python3 manage.py migrate
Create your models in the model directory. Let us create a simple ToDo model-
class Todo(models.Model):
user = models.ForeignKey(User, on_delete=models.CASCADE)
title = models.CharField(max_length=500)
done = models.BooleanField(default=False)
created_at = models.DateTimeField(auto_now_add=True)
Add Graphene library and todo app in to your settings.py
INSTALLED_APPS = [
…
‘rest_framework’,
‘graphene_django’,
‘todo’,
]
Configure the URL in the urls.py file.
from django.contrib import admin
from django.urls import path, include
from rest_framework import routers
from graphene_django.views import GraphQLView
from todo.rest import views
from example.schema import schema
router = routers.DefaultRouter()
router.register(r’todos’, views.TodoViewSet)
urlpatterns = [
path(‘admin/’, admin.site.urls),
path(‘graphql/’, GraphQLView.as_view(graphiql=True, schema=schema)),
]
Create a new file called schema.py. In the schema.py add the graphene schema -
import graphene
from todo.graphql.queries import AllTodosQuery
from todo.graphql.mutations import CreateTodoMutation
class RootQuery(AllTodosQuery, graphene.ObjectType):
pass
class RootMutation(graphene.ObjectType):
create_todo = CreateTodoMutation.Field()
pass
schema = graphene.Schema(query=RootQuery, mutation=RootMutation)
Create a graphql folder that will have 3 files- queries.py, types.py and mutations.py. In types.py we will add the types for our schema -
from graphene_django.types import DjangoObjectType
from django.contrib.auth.models import User
from todo.models import Todo
class TodoType(DjangoObjectType):
class Meta:
model = Todo
class UserType(DjangoObjectType):
class Meta:
model = User
only_fields = [‘id’, ‘first_name’, ‘lastname’, ‘username’]
When using GraphQL there is only a single endpoint called GraphQL. Types specify which Django model we need to use in the API. Queries are used to retrieve the data like a GET Request. Mutations are used to POST or Update the data.
In the mutation.py define our mutations -
import graphene
from todo.models import Todo
from todo.graphql.types import TodoType
class CreateTodoMutation(graphene.Mutation):
todo = graphene.Field(TodoType)
class Arguments:
title = graphene.String()
done = graphene.Boolean()
@classmethod
def mutate(cls, root, info, title, done, *args, **kwargs):
user = info.context.user
todo = Todo.objects.create(user=user, title=title, done=done)
return CreateTodoMutation(todo=todo)
And finally in the queries.py, define the queries . We will use this retrieve all the data from the server.-
import graphene
from todo.graphql.types import TodoType
from todo.models import Todo
class AllTodosQuery(graphene.ObjectType):
all_todos = graphene.List(TodoType, done=graphene.Boolean())
def resolve_all_todos(self, info, done=None, *args, **kwarg):
todos = Todo.objects.all()
if done is not None:
todos.filter(done=done)
return todos
Run the Django server and create some data on the server. Use Postman to retrieve the data on the endpoint /graphql/ -
query{
allTodos {
id
title
done
}
}
This will fetch the data from the server. For creating a data use mutations-
mutation {
createTodo(title:” Good”, done: true) {
todo {
id
title
done
createdAt
}
}
}
Hence we saw how we can easily fetch or create data using graphene in a Django project.
We are a ERP Development Company that offers pragmatic, streamlined application development for your enterprise. Our wide-ranging development solutions in Python, Java, Angular, PostgreSQL, Django, and more cover all your software needs from accounting, security, database management to eCommerce, web, and mobile application development. Get in touch with our experts to implement these technologies in your ERP system NOW!