Django-cms and GraphQL

Michał Dziadowicz
Michał Dziadowicz Python Developer

Read time: 5 min

Oct 06, 2021

Adding GraphQL to DjangoCMS allows exposing data through an api in a structured way. This can be used to build a cms frontend in other technologies or integrate a cms with more applications.

Installing packages

Install package ‘graphene-django’ from pip. This will also install:

  • graphene
  • graphql-core
  • graphql-relay

Package graphene enables main functionality of graphql and graphene-django allows using django models as nodes in graphql.


In the add ‘graphene_django’ to INSTALLED_APPS and add configuration for graphene:

    "SCHEMA": "common.schema.schema"

where SCHEMA points to a file that will contain schema definitions.

Inside add

from graphene_django.views import GraphQLView

and to ‘urlpatterns`

path("graphql", GraphQLView.as_view(graphiql=True))

Where option `graphiql` will enable an interactive console in the web browser.

Adding a schema

Next step is to define a schema. Create a file and import DjangoObjectType.

import graphene
from graphene_django import DjangoObjectType

Create a class Query that will hold all of graphql queries:

class Query(graphene.ObjectType):

Add Query class to schema:

schema = graphene.Schema(query=Query)

The schema variable is the one that is pointed to in the settings file.

Next step is to create an object that can be returned by query. For django models you have to inherit from DjangoObjectType. Class names in graphql usually end with Type on Node. Inside Meta class configure what django model will use. If a model uses parler for translation of fields then for every translated field you have to manually define a type and source for graphene fields.

class PersonType(DjangoObjectType):
    name = graphene.String(source='name')
    description = graphene.String(source='description')

    class Meta:
        model = Person
        interfaces = (graphene.Node,)

Inside Query class add two new queries

people = graphene.List(PersonType)
person = graphene.Field(PersonType, id=graphene.String())

First one is for returning collections of people and the second one for returning a single object by its ID.

Next step is to add a function that can populate return types with data. For that you have to add a `resolve_*` function inside a Query class. Because the person class defines a Node interface, therefore all object ids will be encoded with base64 in the form `model:ID`. To get id back use `from_global_id` function.

from graphql_relay.node.node import from_global_id

def resolve_people(root, context, **kwargs):
    return Person.objects.all()

def resolve_person(root, context, id):
    return Person.objects.get(pk=from_global_id(id)[1])

Go to `localhost/graphql` interactive console and run:

query getPeople {
  people {

`getPeope` is a convenient query name that doesn’t matter. `people` is the actual query defined in the Query class, and `id`, `name`, `email` are fields in the django model that will be returned.

To query for specific person use:

query getPersonById {
person(id: "UGVyc29uVHlwZTo2") {

Where ID can be obtained from people's query.

To add “searching” and “pagination” to people query add two new input parameters for query:

people = graphene.List(PersonType, first=graphene.Int(), search=graphene.String())

and inside a resolver function, use these parameters to modify a QuerySet to return only interesting entities. This will enable searching inside an email field and returning only X first matches.

def resolve_people(root, context, first=None, search=None, **kwargs):
    qs = Person.objects.all()

    if search:
        filter = Q(email__icontains=search)
        qs = qs.filter(filter)

    if first:
        qs = qs[:first]

    return qs

Go to `localhost/graphql` interactive console and run:

query getPeople {
    people(search:"michal") {

to search for everyone with email containing string michal, or

query getPeople {
    people(first: 5) {

to get the first 5 email addresses.

To add a mutation that can modify an object create a new class:

class PersonMutation(DjangoObjectType):
    class Meta:
        model = Person

    class Arguments:
        id = graphene.ID()
        name = graphene.String(required=True)
        email = graphene.String(required=True)

    person = graphene.Field(PersonType)

    def mutate(cls, root, info, id, name, email):
        person = Person.objects.get(pk=from_global_id(id)[1]) = name = email
        return PersonMutation(person=person)

where Meta defines which django model to use, Arguments class defines a list of arguments that will be used in mutation query and a mutate method that takes arguments, updates a model and returns a mutation class.

Create a new mutations class:

class Mutation(graphene.ObjectType):
    update_person = graphene.Field(PersonMutation)

and add it to schema:

schema = graphene.Schema(query=Query, mutation=Mutation)


Graphene is a great library that can help expose endpoints with a relatively little configuration. Adding new endpoints is simple when you get a grasp of graphene code conventions. This allows rapid development of APIs that expose data in logical and easy to follow ways.

Michał Dziadowicz
Michał Dziadowicz The high-skilled software engineer who is constantly developing his skills and competency within the challenging projects.

Read time: 5 min

Oct 06, 2021

Schedule /a meeting/

with our specialist Michał Maj

Michał Maj
Michał Maj Business Development Manager

Read more from our brave's writers

Our mission is to be /trusted partner
to our clients/
in the field of webplatform
development & staff augmentation

Check our rank

  • development
  • clutch
Item 1 of 3

0 Professionals

0 Finished project


  • “Not afraid of doing even the most difficult tasks and proposing innovative solutions. They don’t avoid challenges, rely on new technologies, and - most importantly - always carry the projects through from the beginning to the end.”

    Adam Bogdan
    Adam Bogdan Python Developer
Item 1 of 8

/keep in touch/

We're happy to help! Leave your contact data, and we will get in touch with you within one business day.

Tell us about your needs, ask about our experience, portfolio, and even partnership programs.

Contact us

Thinking of

We are on constant lookout for new talents to join our Brave team! Don’t wait and check our latest Job openings!