Django Rest Framework Tutorial: Todo API

Django Rest Framework Tutorial: Todo API

Django REST framework is a powerful and flexible toolkit for building Web APIs. It is a powerful library that sits on top of existing Django projects to add robust web APIs. If you have an existing Django project with only models and a database--no views, urls, or templates required--you can quickly transform it into a RESTful API with a minimal amount of code. In this tutorial, we'll create a basic Django To Do app web API using serializers, viewsets, and routers.

Prerequisites

You should have a basic understanding of how Django works and a local development configuration with Python 3.

Initial Setup

Let's start by creating a directory for our code, installing Django, and creating a new project. Execute the following on the command line.

$ cd ~/Destkop
$ mkdir todo && cd todo
$ pipenv install django~=3.1.0
$ pipenv shell
(todo) $ django-admin startproject config .
(todo) $ python manage.py startapp todo

We're placing the code on the Desktop but it can live anywhere you choose on your computer. We've used Pipenv to install Django and then enter a dedicated virtual environment. And finally created a new Django project called config which has a todo app.

Since we have a new app, we need to update our INSTALLED_APPS setting. Open config/settings.py with your text editor and add todo at the bottom of the list.

# config/settings.py
INSTALLED_APPS = [
  ...
  'todo', # new
]

Perform our first migration to set up the initial database at this point.

(todo) $ python manage.py migrate

Next, we can create a basic model for our Todo app which will just have a title, description, and add a __str__ method.

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


class Todo(models.Model):
    title = models.CharField(max_length=200)
    description = models.TextField()

    def __str__(self):
        return self.title

Then create a migration file and migrate our change to the project database.

(todo) $ python manage.py makemigrations todo
(todo) $ python manage.py migrate

The final step is to update the admin.py file so the todo app is visible when we log into the admin.

# todo/admin.py
from django.contrib import admin

from .models import Todo

admin.site.register(Todo)

In a normal Django app at this point, we would need to add URLs, views, and templates to display our content. But since our end goal is an API that will transmit the data over the internet, we don't actually need anything beyond our models.py file!

Let's create a superuser account so we can log into the admin and add some data to our model. Follow the prompts to add a name, email, and password. If you're curious, I've used user, user@email.com, and 1234567890 since this example is for learning purposes. Obviously use a name and password that are more secure on a real site!

(todo) $ python manage.py createsuperuser
(todo) $ python manage.py runserver

Navigate to http://127.0.0.1:8000/admin on your browser and log in with your new superuser account.

On the Admin homepage you should see the todo app. Click on the "+ Add" button for Todow and add two new entries we can use. I've called mine the following:

  • title: learn Django; description: learn Django

  • title: learn python; description: learn python

Now it's time for Django Rest Framework.

Django Rest Framework

The first step is to install Django Rest Framework.

On the command line stop the server with Control+c and then enter the following.

(todo) $ pipenv install djangorestframework

Next, add rest_framework app to our INSTALLED_APPS setting

# config/settings.py
INSTALLED_APPS = [
    ...
    'rest_framework', # new
    'todo',
]

The next step is to Configure the URL for our API endpoints in config/urls.py.

# config/urls.py
from django.contrib import admin
from django.urls import path, include

urlpatterns = [
    path('admin/', admin.site.urls),
    path('api/', include('todo.urls'))
]

we added todo.urls but we haven't created it, so let's create a file inside the todo directory and name it urls.py and add these lines:

# todo/urls.py

from django.urls import path
from .views import ListTodo, DetailTodo, CreateTodo


urlpatterns = [
    path('<int:pk>/', DetailTodo.as_view()),
    path('', ListTodo.as_view()),
    path('create', CreateTodo.as_view())
]

we imported the ListTodo, DetailTodo and CreateTodo which we yet have to create these classes. and urlspatterns is where we create our routes. <int:pk> is passing the Primary key as a URL query.

Serializer (JSON)

we need a serializer file to transpile the python queryset to JSON in order to send it over HTTP request. let's go ahead and create a file todo/serializer.py

from rest_framework import serializers
from .models import Todo


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

Importing the Todo Model and exposing the id, title, and description field as JSON in the Meta class. model variable is which model we need to transpile and fields are which fields we need to expose. the id field is created automatically when adding a new object

View

open the todo/views.py file and the logic

from rest_framework import generics
from .serializers import TodoSerializer
from .models import Todo


# Showing the List
class ListTodo(generics.ListAPIView):
    queryset = Todo.objects.all()
    serializer_class = TodoSerializer

# fetching single todo
class DetailTodo(generics.RetrieveAPIView):
    queryset = Todo.objects.all()
    serializer_class = TodoSerializer

# creating one
class CreateTodo(generics.CreateAPIView):
    queryset = Todo.objects.all()
    serializer_class = TodoSerializer

now run the server and head over to 'http://127.0.0.1:8000/api/create`

$(todo) $ python manage.py runserver

it will let you create a new todo, and play around with it.