Build a To-Do application Using Django and React

Sanket Lolge   04 November,2020  

In this blog, we build a Todo application using Django and React.

React is a JS framework that is great for developing SPAs (single page applications) .

Django is a Python web framework that simplifies common practices in web development. Django has been around for a while, meaning most gotcha’s and problems have been solved, and there’s a set of stable libraries supporting common development needs.

For this application, React serves as the front-end or client-side framework, handling UI and getting and setting data via requests to the Django back-end, which is an API built using the Django REST framework (DRF).


To follow along with this blog, you will need to:

  1. Install and set up a local programming environment for Python 3
  2. Install Node.js and Create a Local Development Environment

Setting up the Backend

In this section, we will set up the backend and create all the folders that we need to get things up and running, so launch a new instance of a terminal and create the project’s directory by running this command:

$ mkdir django-todo-react

Next, we will navigate into the directory:

$ cd django-todo-react


Installing Virtualenv

Virtualenv is a Python package. The main function is to separate your project environment from the rest of the system so that whatever you add inside this virtual environment does not affect the rest of your system.

If not installed install it by typing a command on the terminal.

$ python3 -m pip install --user virtualenv

 Now, create the virtual environment for the project using the following command:

$ python3 -m venv env

After creating virtual environment, activate it. 
To activate use following command:

$ source <Environment Name>/bin/activate

Installing Django

$ pip install django

Create a new project called backend:

Next, we will navigate into the newly created backend folder and start a new application called todo. We will also run migrations and start up the server:

$ cd backend

$ python startapp todo

$ python migrate

$ python runserver

Registering the Todo application

We are done with the basic setup for the backend, let’s start with the more advanced things like registering the todo application as an installed app so that Django can recognize it. Open the backend/ file and update the INSTALLED_APPS section as so:


# backend/

# Application definition
    'todo' # add this



Defining the Todo model

Let’s create a model to define how the Todo items should be stored in the database, open the todo/ file, and update it with this code

# todo/

from django.db import models
# Create your models here.

# add this
class Todo(models.Model):
  title = models.CharField(max_length=120)
  description = models.TextField()
  completed = models.BooleanField(default=False)

  def _str_(self):
    return self.title



The code snippet above describes three properties on the Todo model:

  • Title

  • Description

  • Completed


The completed property is the status of a task; a task will either be completed or not completed at any time. Because we have created a Todo model, we need to create a migration file and apply the changes to the database, so let’s run these commands:

$ python makemigrations
$ python migrate


We can test to see that CRUD operations work on the Todo model we created using the admin interface that Django provides out of the box, but first, we will do a little configuration.

Open the todo/ file and update it accordingly:

# todo/

from django.contrib import admin
from .models import Todo # add this

class TodoAdmin(admin.ModelAdmin):  # add this
  list_display = ('title', 'description', 'completed') # add this

# Register your models here., TodoAdmin) # add this



We will create a superuser account to access the admin interface with this command:

$ python createsuperuser

You will be prompted to enter a username, email, and password for the superuser. Be sure to enter details that you can remember because you will need them to log in to the admin dashboard shortly.

Let’s start the server once more and log in on the address — http://localhost:8000/admin

$ python runserver


We can create, edit, and delete Todo items using this interface. Let’s go ahead and create some:

Awesome work so far, be proud of what you’ve done! In the next section, we will see how we can create the API using the Django REST framework.


Setting up the APIs

Now, we will quit the server (CONTROL-C) then install the djangorestframework and django-cors-headers

$ pip install djangorestframework

$ python -m pip install django-cors-headers


We need to add rest_framework and corsheaders to the list of installed applications, so open the backend/ file and update the INSTALLED_APPS and MIDDLEWARE sections accordingly:

# backend/

# Application definition
    'corsheaders',            # add this
    'rest_framework',         # add this

    'corsheaders.middleware.CorsMiddleware',    # add this


Add this code snippet to the bottom of the backend/ file:

# we whitelist localhost:3000 because that's where frontend will be served

Django-cors-headers is a python library that will help in preventing the errors that we would normally get due to CORS. rules. In the CORS_ORIGIN_WHITELIST snippet, we whitelisted localhost:3000 because we want the frontend (which will be served on that port) of the application to interact with the API.


Creating serializers for the Todo model

We need serializers to convert model instances to JSON so that the frontend can work with the received data easily. We will create a todo/ file:

$ touch todo/

Open the file and update it with the following code.

# todo/

from rest_framework import serializers
from .models import Todo

class TodoSerializer(serializers.ModelSerializer):
  class Meta:
    model = Todo
    fields = ('id', 'title', 'description', 'completed')



Creating the View

We will create a TodoView class in the todo/ file, so update it with the following code:

# todo/

from django.shortcuts import render
from rest_framework import viewsets          # add this
from .serializers import TodoSerializer      # add this
from .models import Todo                     # add this

class TodoView(viewsets.ModelViewSet):       # add this
  serializer_class = TodoSerializer          # add this
  queryset = Todo.objects.all()              # add this