Graphql in django using Graphene-Django
GraphQL is a powerful query language for APIs that gives clients exactly the data they need, and Django is a robust web framework for building scalable web applications. In this guide, we'll explore how to integrate GraphQL into a Django project using Graphene-Django library, allowing us to build flexible, efficient APIs with less overhead and greater control over data fetching.
Before starting this guide, it is highly recommended to read this guide: GraphQL in Python using Graphene
In this guide, I assume that you are familiar with basics of Django.
Open terminal or command prompt based on your OS and create a working directory and go inside the directory
mkdir graphql_with_django
cd graphql_with_django
Create a virtual environment and activate it.
python -m venv .venv
source .venv/bin/activate # for linux/macos
.venv\Scripts\activate # for windows
We will install django and graphene-django . Open your terminal/command prompt and
pip install django
pip install graphene-django
Now, we create our django project and also create an app named course.
django-admin startproject core . # create project inside current directory
django-admin startapp course
Now, lets add graphene_django and course to INSTALLED_APPS in settings.py file of django project.
INSTALLED_APPS = [
...
"graphene_django",
"course",
]
Now, lets add URL for graphql in core/urls.py
# urls.py
from django.urls import path
from django.views.decorators.csrf import csrf_exempt
from graphene_django.views import GraphQLView
urlpatterns = [
# ...
path("graphql/", csrf_exempt(GraphQLView.as_view(graphiql=True))),
]
- We use
csrf_exemptdecorator to make sure that CSRF protection enabled in Django application doesn't block our API clients from creating POST request tographqlendpoint. However, this approach is not recommended for production environments, as it disables an important security mechanism that helps prevent Cross-Site Request Forgery(CSRF) attacks. GraphQLViewis a class-based view from Graphene-Django, used to handle GraphQL queries.graphiql=Trueenables the GraphiQL UI — a browser-based IDE where you can write and test GraphQL queries interactively.
Now, create schema.py file inside core folder and create schema in core/schema.py
import graphene
class Query(graphene.ObjectType):
pass
class Mutation(graphene.ObjectType):
pass
schema = graphene.Schema(query=Query, mutation=Mutation)
If this schema variable confuses you, explore one of these links:
GraphQL in Python using Graphene
Building a GraphQL API in Python with PostgreSQL Integration
Now, add schema to core/settings.py.
# ...
GRAPHENE = {
"SCHEMA": "core.schema.schema",
}
Lets create Course model in our course/models.py.
from django.db import models
class Course(models.Model):
title = models.CharField(max_length=100, blank=False, unique=True)
description = models.TextField()
language = models.CharField(max_length=20, default="English", blank=True)
price = models.PositiveIntegerField()
currency = models.CharField(max_length=10)
def __str__(self):
return str(self.title)
Migrate the database changes and register this Course model to admin by editing course/admin.py file.
from django.contrib import admin
from course.models import Course
admin.site.register([Course])
Create a superuser to login to admin panel and add some data to Course model.
Now, let's add queries to course/schema.py file to get course lists and course by id.
import graphene
from graphene_django import DjangoObjectType
from .models import Course
class CourseType(DjangoObjectType):
class Meta:
model = Course
exclude = ()
class Query(graphene.ObjectType):
courses = graphene.List(CourseType)
course_by_id = graphene.Field(CourseType, id=graphene.Int()) # arugment must be declared here
def resolve_courses(self, info):
return Course.objects.all()
def resolve_course_by_id(self, info, id):
try:
course = Course.objects.get(id=id)
return course
except Exception as e:
return Exception(f"Error: {str(e)}")
- We create
CourseType, inheriting fromDjangoObjectType. This will create a Type based on modelCourse. excludetells Django which fields to leave out when generating the type. Alternatively, we can addfields, to include fields that we want in our type. For eg:fields = ["title", "price"]resolve_courses(), gives us list of all coursesresolve_course_by_id(), gives us course information based onidprovided with query request.
Now, lets add Mutation to course/schema.py.
#...
class CreateCourse(graphene.Mutation):
class Arguments:
title = graphene.String(required=True)
description = graphene.String()
language = graphene.String(default_value="English")
price = graphene.Int()
currency = graphene.String(default_value="NPR")
ok = graphene.Boolean()
course = graphene.Field(CourseType)
def mutate(self, info, title, description, language, price, currency):
try:
course = Course.objects.create(
title=title,
description=description,
language=language,
price=price,
currency=currency
)
return CreateCourse(course=course, ok=True)
except Exception:
return CreateCourse(course=None, ok=False)
class Mutation(graphene.ObjectType):
create_course = CreateCourse.Field()
Here, we create
CreateCourseclass that hasmutate()method to handle creation ofCourseobject. This mutation returns two main fields:ok: A boolean value that simply tells us whether the course was created successfully or not.
course: The newly created course object, containing all the relevant course details like title, description, language, and price.
These fields help the client know if the operation worked and, if it did, access the newly created course data immediately.
Also, we create
Mutationclass that contains field to handle various mutations. In our case, we have only one field,create_course.
Now, we will extend Query and Mutation on core/schema.py from Query and Mutation from course/schema.py
# ...
import course.schema
class Query(course.schema.Query, graphene.ObjectType):
pass
class Mutation(course.schema.Mutation, graphene.ObjectType):
pass
# ...
With the queries and mutations ready, it’s time to test them out right in the browser. Open your favorite browser and open http://localhost:8000/graphql. Make sure you have started your django web application.
query allCourses{
courses{
id
title
description
price
currency
language
}
}
mutation courseCreator{
createCourse(
title:"How to install Flask on your machine",
description: "A course on installing Flask on your machine",
language:"English",
price: 200
)
{
ok
course{
id
title
description
price
currency
language
}
}
}
You can find code for this guide on rasbin111/tutorials.
To explore more about graphene_django, you can visit documentation: Graphene-Django.