DEV Community

Tonny Kirwa
Tonny Kirwa

Posted on • Updated on

Building a Todo application using Django, Django Rest Framework, GraphQL, and PostgreSQL

Today, we are building a Todo application using Django, Django Rest Framework, GraphQL, and PostgreSQL. This is a powerful tech stack that can help you create a robust and scalable application. Let's break down the steps to achieve this:

Setting Up Django Project
Start by creating a new Django project or using an existing one. You can use the following command to create a new project:

   django-admin startproject projectname
Enter fullscreen mode Exit fullscreen mode

Setting Up PostgreSQL Database
Install the PostgreSQL database and configure it in your Django project's settings. Update the DATABASES configuration in your settings.py file with your PostgreSQL database credentials.

  1. Setting Up Django Rest Framework Install Django Rest Framework using pip:
   pip install djangorestframework
Enter fullscreen mode Exit fullscreen mode
  1. Add 'rest_framework' to the INSTALLED_APPS list in your settings.py file Your INSTALLED_APPS might look something like this after adding DRF:
   INSTALLED_APPS = [
       # ... other apps ...
       'rest_framework',
       # ... more apps ...
   ]
Enter fullscreen mode Exit fullscreen mode
  1. Creating a Todo Model Define a Todo model in one of your Django app's models.py file. For example:
   from django.db import models

   class Todo(models.Model):
       title = models.CharField(max_length=200)
       completed = models.BooleanField(default=False)
       created_at = models.DateTimeField(auto_now_add=True)
Enter fullscreen mode Exit fullscreen mode
  1. Migrating the Database Run the migrations to create the necessary database tables:
   python manage.py makemigrations
   python manage.py migrate
Enter fullscreen mode Exit fullscreen mode
  1. Creating Django Rest Framework API Create a serializer for the Todo model, views using Django Rest Framework's class-based views, and wire up the URLs for API endpoints.

Setting Up GraphQL
Install the graphene-django package to integrate GraphQL into your Django project:

   pip install graphene-django
Enter fullscreen mode Exit fullscreen mode

Create GraphQL schema and types for your Todo model.

Defining GraphQL Queries and Mutations
Defining GraphQL queries and mutations involves creating a schema that outlines the available operations and their input/output types. In your case, for a Todo application, you'll want to define queries to fetch Todo items and mutations to create, update, and delete them. Here's how you can do that using the graphene-django package in a Django project:

Create GraphQL Schema
In one of your Django app files, typically schema.py, define your GraphQL schema and types. Here's an example for a Todo app:

   import graphene
   from graphene_django.types import DjangoObjectType
   from .models import Todo

   class TodoType(DjangoObjectType):
       class Meta:
           model = Todo

   class Query(graphene.ObjectType):
       todos = graphene.List(TodoType)

       def resolve_todos(self, info):
           return Todo.objects.all()

   class CreateTodo(graphene.Mutation):
       class Arguments:
           title = graphene.String()

       todo = graphene.Field(TodoType)

       def mutate(self, info, title):
           todo = Todo(title=title)
           todo.save()
           return CreateTodo(todo=todo)

   class Mutation(graphene.ObjectType):
       create_todo = CreateTodo.Field()

   schema = graphene.Schema(query=Query, mutation=Mutation)
Enter fullscreen mode Exit fullscreen mode

In this example, the TodoType is a GraphQL type that maps to your Todo model. The Query class defines the todos query to fetch all Todo items. The Mutation class defines the create_todo mutation to create a new Todo.

  1. Wire Up URLs: In your project's urls.py file, you need to create a GraphQL endpoint and connect it to the schema:
   from django.urls import path
   from graphene_django.views import GraphQLView

   urlpatterns = [
       # ... other URL patterns ...
       path('graphql/', GraphQLView.as_view(graphiql=True, schema=schema)),
   ]
Enter fullscreen mode Exit fullscreen mode

This sets up the /graphql/ endpoint for your GraphQL API. The graphiql=True argument enables the interactive GraphiQL interface for testing your queries and mutations.

After setting up your schema and URLs, you can use the GraphiQL interface to test your queries and mutations by accessing http://localhost:8000/graphql/ (assuming your development server is running on the default port).

Integrating Django Rest Framework (DRF) with GraphQL


Integrating Django Rest Framework (DRF) with GraphQL can be achieved by using the graphene-django library for GraphQL and leveraging DRF's serializers and views. This way, you can keep your existing DRF infrastructure for certain operations while using GraphQL for others. Here's how you can integrate the two:

Install graphene-django:
If you haven't done so already, install the graphene-django package using the following command:

   pip install graphene-django
Enter fullscreen mode Exit fullscreen mode

Define GraphQL Types:
In your app's schema.py, define GraphQL types for the models you want to expose through GraphQL. Since you're using DRF, you can use DRF serializers to facilitate the conversion between Django models and GraphQL types.

   import graphene
   from graphene_django.types import DjangoObjectType
   from .models import Todo
   from .serializers import TodoSerializer  # Your DRF serializer

   class TodoType(DjangoObjectType):
       class Meta:
           model = Todo

   class Query(graphene.ObjectType):
       todos = graphene.List(TodoType)

       def resolve_todos(self, info):
           queryset = Todo.objects.all()
           return queryset

   schema = graphene.Schema(query=Query)
Enter fullscreen mode Exit fullscreen mode

Use DRF Serializers in Mutations:
You can continue using DRF serializers in your GraphQL mutations to handle data input. Define GraphQL mutations that use DRF serializers to create, update, or delete objects.

   class CreateTodo(graphene.Mutation):
       class Arguments:
           title = graphene.String()

       todo = graphene.Field(TodoType)

       def mutate(self, info, title):
           serializer = TodoSerializer(data={'title': title})
           if serializer.is_valid():
               todo = serializer.save()
               return CreateTodo(todo=todo)
           return CreateTodo(todo=None)

   class Mutation(graphene.ObjectType):
       create_todo = CreateTodo.Field()

   schema = graphene.Schema(query=Query, mutation=Mutation)
Enter fullscreen mode Exit fullscreen mode

Wire Up URLs:
In your project's urls.py, create a GraphQL endpoint that uses the GraphQLView from graphene-django and set up DRF views for your other API operations:

   from django.urls import path
   from graphene_django.views import GraphQLView
   from rest_framework.routers import DefaultRouter
   from .views import TodoViewSet  # Your DRF viewset

   router = DefaultRouter()
   router.register(r'todos', TodoViewSet)

   urlpatterns = [
       path('graphql/', GraphQLView.as_view(graphiql=True, schema=schema)),
       path('api/', include(router.urls)),
   ]
Enter fullscreen mode Exit fullscreen mode

In this example, you're creating a DRF router for the TodoViewSet and a GraphQL endpoint at /graphql/.

This integration allows you to use both GraphQL and DRF in parallel, using the strengths of each for different parts of your application. Be sure to adjust the code to match your project's structure, models, serializers, and views.

Testing and Running:
Test your API endpoints and GraphQL queries/mutations using tools like Postman or Insomnia. Run your Django development server:

```
python manage.py runserver
```
Enter fullscreen mode Exit fullscreen mode

Each step involves more detailed configuration and coding. Be sure to refer to the documentation for each technology (Django, Django Rest Framework, GraphQL, and PostgreSQL) to get the most accurate and up-to-date instructions.

Top comments (0)