How to perform CRUD functionalities in Django Rest Framework

Django Rest framework is a powerful toolkit for building web APIs.

What is an API?

An API (Application Programming Interface) is a set of rules shared by a particular service. These rules determine in which format and with which command set your application can access the service, as well as what data this service can return in the response. It acts as a layer between your application and external service.

REST API (Representational state transfer) is an API that uses HTTPS requests for communication with web services. From the python site, the REST API can be viewed as a data source located on an internet address that can be accessed in a certain way through certain libraries.

Types of Requests:

GET: retrieve information like a search result

POST: adds new data to the server

PUT: changes existing information

DELETE: deletes existing information

Status Codes

200-OK. The request was successful.

204-No content. The server successfully processed the request and did not return any content.

301-Moved permanently. The server responds that the requested page(endpoint) has been moved to another address and redirects to this address.

400-Bad request. The server cannot process the request because of the client-side errors (incorrect request format).

401-Unauthorized. Occurs when authentication failed due to incorrect credentials or even their absence.

403-Forbidden. Access to the specified resource is denied.

404-Not found. The requested resource was not found on the server.

500-Internal Server Error. Occurs when an unknown error has occurred on the server.

Enough with the theory part. Let’s see how we can create CRUD functionalities in the Django Rest framework.

I will create a small to-do list application to guide us through the process.

Steps to follow.

  1. Create a project and set up a virtual environment.
  2. Activate virtual environment
  3. Install Django using pip
  4. Create a project and an app

Create a Django Project and set up a virtual environment.

The first thing to do whenever you are creating Django projects is to set up your virtual environment where you can work in isolation. Let’s start. Install venv package to allow you to create a virtual environment. On your terminal use the following command to create virtual environment.

$ python3 -m venv env 

If you ls you will see your environment created. For my case, I created env as my environment.

To activate your environment, use the following command.

source env/bin/activate

After the environment is activated, let’s install Django using the pip command.

pip install django

Create a requirements.txt file to store all your installations so that the next time someone is using your applications, it will be easy to start off. An easy way to create requirements is to use the freeze command.

pip freeze > requirements.txt

And to do an installation from the requiremets.txt file, use the following command.

pip install -r requiremets.txt

Create a Django Project

To create a Django project, we use the following command.

django-admin startproject myapi .

Take note of the period in the end, it will help create a project from the current directory.

After this is done, create an app.

python manage.py startapp todoapi

The last thing before we can start our server is to go to settings.py and add your created app to the installed apps section. From here the best thing is to open your project using Visual Studio or Pycharm. For me, I will be using Pycharm.

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    
    'todoapi',# our app
]

From here you can test if the server is running

python manage.py runserver

if you see the following as output, then we are good to continue.

System check identified no issues (0 silenced).

You have 18 unapplied migration(s). Your project may not work properly until you apply the migrations for app(s): admin, auth, contenttypes, sessions.
Run 'python manage.py migrate' to apply them.
July 13, 2022 - 07:03:07
Django version 4.0.6, using settings 'myapi.settings'
Starting development server at http://127.0.0.1:8000/
Quit the server with CONTROL-C.

Go to the given IP address to see the outcome.

Let’s render something rather than the default Django output by adding our app to the projects urls.py section.

#myapi.urls
from django.contrib import admin
from django.urls import path, include

urlpatterns = [
    path('admin/', admin.site.urls),
    path('api/', include('todoapi.urls')), # add this todoapi.urls 
]

Also to keep our URLs neat and tidy, go to todoapi and create a urls.py

#todoapi urls.py
from django.urls import path
from . import views 

urlpatterns = [
    path('', views.home, name='home'),
]

Go to todoapi views.py and create the first view of our rest API.

#todoapi/views.py
from django.shortcuts import render
from django.http import HttpResponse


def home(request):
    return HttpResponse("My first api")

You are supposed to see “my first API from the browser”. This means we are good to create our API now.

Create Django Rest API

To start creating a rest API, you need to install djangorestframework and add it to your installed apps in the settings.py

pip install djangorestframework

Then you need to add it to your installed apps

INSTALLED_APPS = [
    ...
    'rest_framework',
]

Also you can add it to your requirements.txt file

pip freeze > requirements.txt 

To begin with, we are going to use function based views therefore we need decorators. For function based views, we use @api_view.

Go to models.py and add the following

#todoapi models.py
from django.db import models


class Todo(models.Model):
    title = models.CharField(max_length=150)
    completed = models.BooleanField(blank=True, null=True, default=False)

    def __str__(self):
        return self.title

To begin, lets create a serializers.py file in our todoapi app first.

#todoapi serializers.py
from rest_framework import serializers

from todoapi.models import Todo


class TodoSerializer(serializers.ModelSerializer):
    class Meta:
        model = Todo
        fields = '__all__'

You need to make migrations for the serializer tables to be created.

$ python manage.py makemigrations
$ python manage.py migrate 

From here you can create admin account so that you can insert the test data. to create admin panel use the following command.

$ python manage.py createsuperuser
Username (leave blank to use 'nextgen'): admin
Email address: 
Password: 
Password (again): 
Superuser created successfully.

The next thing is to register admin in the admin dashboard. use the following.

from django.contrib import admin

# Register your models here.
from todoapi.models import Todo

admin.site.register(Todo)

Running CRUD operations

List Request

To start performing CRUD operations, lets start with the List Operations, this will show all the todos we have in our database. List is a GET operations, so make sure to add that

Go to views.py and add the following.

@api_view(['GET'])
def list_view(request):
    todos = Todo.objects.all()
    serializer = TodoSerializer(todos, many=True)
    return Response(serializer.data, status=status.HTTP_200_OK)

Create a url corresponding to the above view.

path('todo-list/', views.list_view, name='todo-list')

Detail Request

The next thing is to create a detail view, also we are going to use GET to retrieve data.

@api_view(['GET'])
def detail_view(request, pk):
    todo = Todo.objects.get(id=pk)
    serializer = TodoSerializer(todo, many=False)
    return Response(serializer.data)

Note we are using primary key to retrieve specific item.

Create corresponding url for detail view set.

path('detail-view/<int:pk>/', views.detail_view, name='detail-view')

Create Request

Here we are using POST to post data into the database. Use the following code

@api_view(['POST'])
def create_view(request):
    serializer = TodoSerializer(data=request.data)

    if serializer.is_valid():
        serializer.save()
    return Response(serializer.data, status=status.HTTP_201_CREATED)

Add corresponding url path

 path('create-todo/', views.create_view, name='create-todo'),

For testing purposes you can use Insomnia or postman or you can stick to the one provided once you access the API on your browser.

Update request

To update a given request we use POST method. use the following code.

@api_view(['POST'])
def update_view(request, pk):
    todo = Todo.objects.get(id=pk)
    serializer = TodoSerializer(instance=todo, data=request.data)

    if serializer.is_valid():
        serializer.save()
    return Response(serializer.data, status=status.HTTP_202_ACCEPTED)

Add corresponding url path

path('update-todo/<int:pk>/', views.update_view, name='update-todo'),

Delete request

To use delete request, DELETE options is called. Use the following code.

@api_view(['DELETE'])
def delete_view(request, pk):
    todo = Todo.objects.get(id=pk)
    todo.delete()
    return Response("Todo deleted successfully", status=status.HTTP_204_NO_CONTENT)

Add corresponding url path accordingly.

path('delete-todo/<int:pk>/', views.delete_view, name='delete-todo'),

Conclusion

We have successfully performed CRUD operations on Django Rest API. To take it further you can use swaggerUI to visualize your API or you can connect to any frontend libraries such React, Vue, Svelte or use Vanilla Javascript.

About Mason Kipward

I am a technology enthusiast who loves to share gained knowledge through offering daily tips as a way of empowering others. I am fan of Linux and all other things open source.
View all posts by Mason Kipward →

Leave a Reply

Your email address will not be published.