A Step-by-Step Guide to CRUD Operations with Django and GraphQL

nitish96
Nitish Sharma
Published on: June 28, 2025
Updated on: June 28, 2025
A Step-by-Step Guide to CRUD Operations with Django and GraphQL blog

We are learn  step-by-step guild on creating a fully functional blog API using Django and GraphQL. We will cover everything from settings up the project to implementing all CRUD operations. GraphQL offers a powerful and flexible alertnative to REST for building APIs, and integrating it with Django is a seamless process thanks to the graphene-django library.

Step 1:  Project Setup and Installation

First, we need to generate our development environment and install then necessary packages.

1. Create a Project Directory and Virtual Envirenment

Open command promt or terminal

mkdir django_crud
cd django_crud

# create a virtual environment and activate virtual enviroment
python -m venv env

source env/bin/activate #On Linux and Mac
env/Scripts/activate # On Windows

2. Install Django and Graphene

pip install django graphene-django django-cors-headers
  • django: The web framework.
  •  graphene-django: The library that integrates GraphQL with Django.
  • django-cors-headers: This will be useful for allowing a future frontend application to communicate with our API.

3. Start the Django Project and App

django-admin startproject crud_project .
python manage.py startapp posts
  • startproject crud_project .: Creates a project named blog_project in the current directory (.).
  • startapp employee: Creates a new app within our project called employee to handle blog-related logic.

4. Configure Settings.py

Open crud_project/settings.py and make the following additions:

# crud_project/settings.py

INSTALLED_APPS = [
    # ... other apps
    'django.contrib.staticfiles',

    # Third-party apps
    'graphene_django',
    'corsheaders',

    # Our app
  'employee',
]

# Add Graphene-Django settings
GRAPHENE = {
    "SCHEMA": "blog_project.schema.schema"
}

# Add CORS Middleware
MIDDLEWARE = [
    'corsheaders.middleware.CorsMiddleware', # Add this line
    'django.middleware.security.SecurityMiddleware',
    # ... other middleware
]

# Allow all origins for development purposes
CORS_ALLOW_ALL_ORIGINS = True

Step 2: Creating The Blog Employee Model

Now, let's define the database structure for our blog employee.

1. Define the Model

Open employee/models.py and add the Employee model.

# posts/models.py
from django.db import models

class Employee(models.Model):
  name = models.CharField(max_length=200)
qualification = models.CharFiel(max_length=200)
  address = models.TextField()
    created_at = models.DateTimeField(auto_now_add=True)

    def __str__(self):
        return self.title

2. Create and Apply Migrations

These commands will create the Employee table in our database.

python manage.py makemigrations
python manage.py migrate

The terminal shows the output of the commands. makemigrations will report 0001_initial.py being created. migrate will show several lines of "Applying..." messages, ending with Applying posts.0001_initial... OK.

(env) ~/django_graphql_blog$ python manage.py makemigrations
Migrations for 'Employee':
  posts/migrations/0001_initial.py
  - Create model Employee
(env) ~/django_graphql_blog$ python manage.py migrate
Operations to perform:
Apply all migrations: admin, auth, contenttypes, employee, sessions
Running migrations:
  Applying contenttypes.0001_initial... OK
  ... (other lines)
  Applying posts.0001_initial... OK

Step 3: Building the GraphQL Schema

This is where we defined how our data can be queried via GraphQL.

1. Create the App-Lavel Schema

Create a new file: employee/schema.py. This file will define the GraphQL types and queries related to our employee app.

# employee/schema.py
import graphene
from graphene_django import DjangoObjectType
from .models import Employee

# 1. Create a GraphQL type for the Post model
class EmployeeType(DjangoObjectType):
    class Meta:
      model = Employee
      fields = ("id", "name", "qualification","address", "created_at")

# 2. Create a Query class
class Query(graphene.ObjectType):
  all_employees = graphene.List(EmployeeType)
  employee_by_id = graphene.Field(EmployeeType, id=graphene.String())

  def resolve_all_employees(root, info):
        # We can easily optimize query performance here
      return Employee.objects.all()

  def resolve_employee_by_id(root, info, id):
        try:
          return Employee.objects.get(pk=id)
        except Post.DoesNotExist:
            return None

schema = graphene.Schema(query=Query)

2. Create the Project-Lavel Schema

Now, create a new file in your project directory: crud_project/schema.py. This will be our root schema that combines schema fromall our apps.

# crud_project/schema.py
import graphene
import employee.schema

class Query(employee.schema.Query, graphene.ObjectType):
    # This class will inherit from multiple Queries
    # as we begin to add more apps to our project
    pass

schema = graphene.Schema(query=Query)

3. Configure the GraphQL URL EndPoint.

Finally, let's add our schema at a URL. Open crud_project/urls.py

# crud_project/urls.py
from django.contrib import admin
from django.urls import path
from django.views.decorators.csrf import csrf_exempt
from graphene_django.views import GraphQLView
from .schema import schema


urlpatterns = [
    path('admin/', admin.site.urls),
    # Add this line for the GraphQL endpoint
  path("graphql", csrf_exempt(GraphQLView.as_view(graphiql=True, schema=schema))),
]
  • csrf_exempt: We disable CSRF protection for our GraphQL endpoint because clients will typically use token-based authentication, not session cookies.

  • graphiql=True: This enables the awesome in-browser GraphiQL IDE for testing our API.

Step 4: Testing the Read Queries

Let's test our queries, First create a sample Employee using the admin panel for easy testing.

1. Create a SuperUser and a Sample Employee

python manage.py createsuperuser

Follow the prompts to create your admin user. Then, register the Employee model in employee/admin.py so you can access it.

# employee/admin.py
from django.contrib import admin
from .models import Employee

admin.site.register(Employee)

Now, run the server (python manage.py runserver), go to http://127.0.0.1:8000/admin/, log in, and create one or two blog employees.

Your browser shows the Django admin interface. You are on the "employees" page, and you have added a Employee with the name "Nitish", qualifcation "MCA" and some address.

2. Test with GraphQL

Navigate to http://127.0.0.1:8000/graphql. You'll see the GraphiQL interface.

Your browser shows the GraphiQL IDE. On the left panel, you have typed a query. On the right, you see the JSON result.

  • Left Panel (Query):
query {
allEmployees {
    id
    name
  qualification

address
  }
}
  • Right Panel (Result)
{
  "data": {
  "allEmployees": [
      {
        "id": "1",
      "title": "Nitish",
      "qualifcation": "MCA",
"address":"Himachal Pradesh"
      }
    ]
  }
}

Step 5: Building the Mutations (Create, Update, Delete)

Now for the C, U, and D of CRUD. We'll define these operations as "Mutations."

  1. Update employee/schema.py with Mutations

     Add the following classes to your employee/schema.py file.

   

# employee/schema.py
# ... (keep existing code: EmployeeType and Query classes)

# --- MUTATIONS ---

# 1. Create Post Mutation
class CreateEmployee(graphene.Mutation):
    class Arguments:
        # Input arguments for the mutation
      name = graphene.String(required=True)
      qualification= graphene.String(required=True)
address = graphene.String(required=True)

    # Output fields
    post = graphene.Field(PostType)

    @classmethod
    def mutate(cls, root, info, title, content):
      employee = Employee(name=name, qualification=qualifcation, address=address)
      employee.save()
      return CreateEmployee(employee=employee)

# 2. Update Post Mutation
class UpdateEmployee(graphene.Mutation):
    class Arguments:
        id = graphene.ID(required=True)
      name = graphene.String()
      qualification= graphene.String()
address = graphene.String()

  employee = graphene.Field(EmployeeType)

    @classmethod
  def mutate(cls, root, info, id, name=None, qualification=None, address=None):
        try:
          employee = Employee.objects.get(pk=id)
          if name:
              employee.name = name
          if qualification:
              employee.qualification = qualification
if address:
employee.address = address
          employee.save()
          return UpdateEmployee(employee=employee)
        except Post.DoesNotExist:
            return None

# 3. Delete Post Mutation
class DeleteEmployee(graphene.Mutation):
    class Arguments:
        id = graphene.ID(required=True)

    # Output field
    ok = graphene.Boolean()

    @classmethod
    def mutate(cls, root, info, id):
        try:
          employee = Employee.objects.get(pk=id)
          employee.delete()
          return DeleteEmployee(ok=True)
        except Post.DoesNotExist:
          return DeleteEmployee(ok=False)

# 4. Register Mutations
class Mutation(graphene.ObjectType):
  create_employee = CreateEmployee.Field()
  update_employee = UpdateEmployee.Field()
  delete_employee = DeleteEmployee.Field()

# 5. Update Schema Definition
# Change this line at the bottom of the file
schema = graphene.Schema(query=Query, mutation=Mutation)

2. Update the Project-Level Schema

Finally, wire up the mutations in crud_project/schema.py.

# crud_project/schema.py
import graphene
import posts.schema

class Query(posts.schema.Query, graphene.ObjectType):
    pass

# Add this Mutation class
class Mutation(posts.schema.Mutation, graphene.ObjectType):
    pass

# Update the schema definition
schema = graphene.Schema(query=Query, mutation=Mutation)

Step 6: Testing the Mutations

You're using the GraphiQL IDE to create a new post.

  • Left Panel (Mutation):
mutation {
createEmployee(name: "Vikas",qualification:"12th", address: "delhi") {
  employee{
      id
    name
qualification
address
      createdAt
    }
  }
}
  •  Right Panel (Result):
 {
  "data": {
  "createEmployee": {
    "employee": {
        "id": "2",
      "name": "Vikas",
"qualifcation":"12th",
"address":"delhi",
        "createdAt": "2025-06-28T11:00:00.123456+00:00"
      }
    }
  }
}

Now you're updating the post you just created.

  • Left Panel (Mutation):
mutation {
updateEmployee(id: "2", name: "Vikas Sharma") {
  employee {
    id
    name
qualification
address
    createdAt
    }
  }
}
  • Right Panel (Result):
 {
  "data": {
  "updateEmployee": {
    "employee": {
        "id": "2",
      "name": "Vikas Sharma",
"qualifcation":"12th",
"address":"delhi",
        "createdAt": "2025-06-28T11:00:00.123456+00:00"
      }
    }
  }
}

Finally, you're deleting the employee.

  • Left Panel (Mutation):
mutation {
  deleteEmployee(id: "2") {
    ok
  }
}
  • Right Panel (Result):
{
  "data": {
  "deleteEmployee": {
      "ok": true
    }
  }
}

Conclusion

Congratulations! You have successfully built a complete CRUD API for a blog using Django and GraphQL. You've learned how to:

  • Set up a Django project with Graphene.

  • Define Django models and map them to GraphQL types.

  • Create queries to read data.

  • Create mutations to create, update, and delete data.

  • Test your API using the powerful GraphiQL interface.

From here, you could expand the project by adding user authentication (so only authors can edit their own posts), pagination for the allEmployees query, or connecting a frontend framework like React or angular.

Comments

Login to leave a comment.

Build Software Application with Impact Hive