Sitemap
Shoomankhatri

Shoomankhatri

Backend Developer

Press enter or click to view image in full size

Django Todo App

3 min readMay 22, 2026

--

In this tutorial, we’ll build a simple Todo API using Django REST Framework with full CRUD functionality.

  1. Install Django + DRF
pip install django djangorestframework

Explanation

  • Django → Web framework (handles backend, database, logic)
  • Django REST Framework (DRF) → Converts Django into an API builder

DRF helps you return data in JSON format

2. Create project + app

django-admin startproject todo_project
cd todo_project
python manage.py startapp todos

Explanation

  • project → Main configuration (settings, URLs)
  • app → Where your actual feature lives (Todo logic)

Think:

  • Project = container
  • App = feature/module

3. Add apps in settings.py

INSTALLED_APPS = [
...
'rest_framework',
'todos',
]

Explanation

  • 'rest_framework' → enables DRF features
  • 'todos' → tells Django to use your app

If you don’t add this, Django won’t recognize your app

4. Create Todo Model (todos/models.py)

from django.db import models
class Todo(models.Model):
title = models.CharField(max_length=255)
completed = models.BooleanField(default=False)
created_at = models.DateTimeField(auto_now_add=True)
def __str__(self):
return self.title

Explanation

__str__ defines how the object is displayed as a string

In simple terms:

“What should Django show when this object is printed or viewed?”

🔍 Without __str__

If you don’t define it, Django shows something like:

Todo object (1)

Explanation

This defines your database table

  • title → task name
  • completed → true/false status
  • created_at → auto timestamp

Django converts this into a SQL table

5. Migrate database

python manage.py makemigrations
python manage.py migrate

Explanation

  • makemigrations → creates migration file
  • migrate → applies changes to database

Without this, your model won’t exist in DB

6. Create Serializer (todos/serializers.py

from rest_framework import serializers
from .models import Todo
class TodoSerializer(serializers.ModelSerializer):
class Meta:
model = Todo
fields = '__all__'

Explanation

Serializer = converter

Converts:

  • Python object → JSON (response)
  • JSON → Python object (request)

Example:

{
"title": "Learn DRF",
"completed": false
}

7. Create Views (CRUD APIs)

Get Shoomankhatri’s stories in your inbox

Join Medium for free to get updates from this writer.

todos/views.py

from rest_framework import generics
from .models import Todo
from .serializers import TodoSerializer
# GET all + POST create
class TodoListCreateView(generics.ListCreateAPIView):
queryset = Todo.objects.all().order_by('-created_at')
serializer_class = TodoSerializer
# GET single + PUT + DELETE
class TodoDetailView(generics.RetrieveUpdateDestroyAPIView):
queryset = Todo.objects.all()
serializer_class = TodoSerializer

Explanation

ListCreateAPIView

Handles:

  • GET /todos/ → get all todos
  • POST /todos/ → create new todo

RetrieveUpdateDestroyAPIView

Handles:

  • GET /todos/1/ → get one todo
  • PUT /todos/1/ → update
  • DELETE /todos/1/ → delete

What is Generics

Generics (in Django REST Framework) are pre-built views that automatically handle common API operations like GET, POST, PUT, and DELETE, so you don’t have to write the logic yourself.

Why use generics?

DRF gives ready-made logic

Instead of writing everything manually:

  • Less code
  • Faster development

8. Create URLs (todos/urls.py)

from django.urls import path
from .views import TodoListCreateView, TodoDetailView
urlpatterns = [
path('todos/', TodoListCreateView.as_view(), name='todo-list-create'),
path('todos/<int:pk>/', TodoDetailView.as_view(), name='todo-detail'),
]

Explanation

This connects:

  • URL → View

Example:

  • /todos/ → list & create
  • /todos/1/ → single item

9. Connect main URLs (todo_project/urls.py)

from django.contrib import admin
from django.urls import path, include
urlpatterns = [
path('admin/', admin.site.urls),
path('api/', include('todos.urls')),
] ,

Explanation

  • /api/todos/ → your API endpoint
  • include() → connects app URLs to project

10. Testing Your API

Create Todo

POST /api/todos/

Body:

{
"title": "Learn Django",
"completed": false
}

Get All Todos

GET /api/todos/

Get One Todo

GET /api/todos/1/

Update Todo

PUT /api/todos/1/

Delete Todo

DELETE /api/todos/1/

Final Understanding

This app follows a clean flow:

Model → Serializer → View → URL → API

Data flow:

  1. User sends request
  2. View handles it
  3. Serializer converts data
  4. Model interacts with DB
  5. Response returned as JSON

Summary

  • Django handles backend logic
  • DRF makes API building easy
  • Generics reduce code
  • Serializer handles JSON conversion

--