Django Rest API in 30 Minutes or so

Saurater Faraday
9 min readMay 26, 2022
Django Rest API in 30 Minutes or so

1. Introduction

In this article, I will walk you through the creating of a Django CRUD API in very simple steps.

This article is based on the video tutorial Python Django + MySQL CRUD API Tutorial https://www.youtube.com/watch?v=WuOjWTnnrfw by art of Engineer.

2. Some Definitions

REST API Definition

API’s have been around for a long time, however they have become more and more popular in recent years with Cloud App. An Application Programming Interface, API, is a simple way to make different applications communicate to each other. A key point is that with API’s, the end user, or API Consumer, need not to know anything about your application architecture, the language it was developed, nor should it care about the database. In the way, a mobile app, a desktop app or web browser app can retrieve (GET), Post, update (PUT) or Delete information across application with a simple call to an API.

Representational state transfer (REST) is a software architectural style that was created to guide the design and development of the architecture for the Web.

A web API that obeys the REST constraints is informally described as RESTful. RESTful web APIs are typically loosely based on HTTP methods to access resources via URL-encoded parameters and the use of JSON or XML to transmit data. (Wikipedia)

3. Installations and Virtual Environment

In this tutorial, we are going to develop a step by step API using Django and Django Rest Framework.

Note: Please stick to the lib versions, as a different version may have some function deprecated.

  1. Python 3.8 — Let us start by downloading and installing Python 3.8
    You can find Windows Files here https://www.python.org/downloads/release/python-380/ or follow a step-by-step guide here https://linuxize.com/post/how-to-install-python-3-8-on-ubuntu-18-04/
  • VENV Installation — Python Virtual Environment — Once you have installed Python==3.8 (please check the version by typing python3.8 (in Linux) and check its version ), the next step it to create a VENV. To do it, type up:
    python3.8 -m venv venv
  • Activating the VENV — type up
    source ./venv/bin/activate

Please note that if you are using Windows, the path may be something like \venv\Scripts\activate.bat

  • Django==3.2.4 — once the venv is active, let us install the other libs. Please type up:
    pip install django==3.2.4
  • Django Rest Framework==3.13.1 — Django REST framework is a powerful and flexible toolkit for building Web APIs.
    pip install djangorestframework==3.13.1
  • Django-Cors-HeadersA Django App that adds Cross-Origin Resource Sharing (CORS) headers to responses. This allows in-browser requests to your Django application from other origins.
    pip install django-cors-headers==3.12.0
  • PyMySQL — It will beused to connect to MySQL
    pip install pymysql==1.0.2
  • MySQL WorkBench — It will be used to connect to the MySQL Database.
    sudo apt update && sudo apt upgrade
    sudo apt install mysql-workbench

4. Connecting to MySQL

Once you have installed MySQL, in this case we are using an Azure Instance, please run MySQL Workbench and set it up like the image below:

  • Hostname: my_hostname
  • Port: 3306
  • Username: my_user name
  • Password: my_password

5. Creating the Database

type up:
create database mytestdb;

Note 1: an empty database named mytestdb will be created. All the tables and fields will be created in Django and migrate thorugh it as well.

Note 2: If you are using Azure, please make sure to disable SSL connection for this lab.

6. Django Project

All Django work starts wit a project, so let us create one named DjangoAPI. To do so, please type up the code below.

Note: Please make sure the “period” is part of the code, otherwise the system will create 2 folders named DjangoAPI.

django-admin startproject DjangoAPI .

Project

The DjangoAPI Project will be created with the file seen above.

A project in Django is a python package that represents the whole web application.

A project in Django basically contains the configuration and setting related to the entire website.

A single project can also have multiple apps in it that can be used to implement some functionality. (Source: Python Guides)

Github https://github.com/saurater/django_rest_api_hello_world/tree/main/DjangoAPI

7. Django APP

An app in Django is a sub-module of a project, and it is used to implement some functionality.

Now, you can refer to an app as a standalone python module that is used to provide some functionality to your project.

We can create multiple apps within a single Django project. And these apps can be independent of one another. (Source: Python Guides)

To create our first app, type up:
python manage.py startapp EmployeeApp

App

A folder with the App name is created with some files we will be working on.

Github https://github.com/saurater/django_rest_api_hello_world/tree/main/EmployeeApp

8. Apps, Middleware and Database Settings

Github https://github.com/saurater/django_rest_api_hello_world/blob/main/DjangoAPI/settings.py

8.1 Apps Settings

We need to let Django know the Apps we will be working with. To do so, open the file \DjangoApi\settings.py, then add the apps below to the INSTALLED_APPS section:

‘EmployeeApp.apps.EmployeeappConfig’,
‘rest_framework’,
‘corsheaders’,

INSTALLED_APPS

8.2 Middleware Settings

  • In order to allow all in-browser requests to your Django application from other origins, please add the line below above the Middleware section:

CORS_ORIGIN_ALLOW_ALL = True

Note: This is something to avoid in production, where just the IP you trust should be allowed in.

  • Additionanly, please add the line below to the Middleware section

‘corsheaders.middleware.CorsMiddleware’

Middleware Settings

8.3 Database Settings

PyMySQL Settings

There is a known bug that requires we to import the pymysql lib. Please add the lines below right before the DATABASE Section:

import pymysql
pymysql.install_as_MySQLdb()

Database Settings

Now we need to let Django know how to access our database. Just add the connection string to your database in this section.

DATABASES = {
‘default’: {
‘ENGINE’: ‘django.db.backends.mysql’,
‘NAME’: ‘mytestdb’,
‘USER’: ‘sam’,
‘PASSWORD’: ‘mypassowrd,
‘HOST’:’myhost’,
‘PORT’: ‘3306’
}
}

Database Settings

9. Django Models

Django Models are built-in features that Django uses to create tables, fields, and various constraints. They are created as a class and each attribute of the model represents a database field. In other words, a Django Model is a Data Table defined as a class.

In our Hello World, we are going to create 2 tables, I mean, 2 classes: Employees and Department. They are created in the views.py file.

ORM (Object-Relational Mapper) Language

No SQL required here. Django uses ORM — Object-Relational Mapper.

The Django ORM is a very powerful tool, and one of the great attractions of Django. It makes writing simple queries trivial, and does a great job of abstracting away the database layer in your application.(source: Yeti)

SQL x ORM — source: Full Stack Python

Github https://github.com/saurater/django_rest_api_hello_world/blob/main/EmployeeApp/models.py

Please change the models.py file as follows:

from django.db import models

class Departments(models.Model):
DepartmentId = models.AutoField(primary_key=True)
DepartmentName = models.CharField(max_length=500)

class Employees(models.Model):
EmployeeId = models.AutoField(primary_key=True)
EmployeeName = models.CharField(max_length=500)
Department = models.CharField(max_length=500)
DateOfJoining = models.DateField()
PhotoFileName = models.CharField(max_length=500)

Models

10. Migrating the Models

Once you models are defined, it is time to create the tables or apply the changes to them in the database. No SQL is required here. Just use the commands below:

migrate, which is responsible for applying and unapplying migrations.

makemigrations, which is responsible for creating new migrations based on the changes you have made to your models.

You should think of migrations as a version control system for your database schema. makemigrations is responsible for packaging up your model changes into individual migration files - analogous to commits - and migrate is responsible for applying those to your database. (source: Django Project)

10.1 makemigrations — So, let get hands on work. In the command line, please make sure yoou are in the same directory as the manage.py file, type up:

python .\manage.py makemigrations EmployeeApp

Once you do that successfully, Python file 0001_initial.py will be automatically created with the model(s) definitions. This file will be used to connect to the database and create the tables or apply the changes to them.

Github https://github.com/saurater/django_rest_api_hello_world/blob/main/EmployeeApp/migrations/0001_initial.py

10.2 migrate — This command will use the file created in hte makemigrations command to connect to the database and create the tables or apply the changes to them.

python manage.py migrate EmployeeApp

Tables created in the database. Please check Mysql Workbench

11. Inserting some records

In Mysql Workbench, let us insert some records. Please run the instructions below:

insert into mytestdb.employeeapp_departments values(1, ‘Finance’);

insert into mytestdb.employeeapp_departments values(2, ‘Administration’);

insert into mytestdb.employeeapp_employees values (1, ‘Sam’, ‘IT’, ‘2022–05–26’, ‘annonymous.png’);

12. Serializers

Serializers allow complex data such as querysets and model instances to be converted to native Python datatypes that can then be easily rendered into JSON, XML or other content types. Serializers also provide deserialization, allowing parsed data to be converted back into complex types, after first validating the incoming data.

The serializers in REST framework work very similarly to Django’s Form and ModelForm classes. We provide a Serializer class which gives you a powerful, generic way to control the output of your responses, as well as a ModelSerializer class which provides a useful shortcut for creating serializers that deal with model instances and querysets. (source: Django Rest Framework)

In order to Serialize the models’ data, let follow the steps below:

12.1 Create the file serializers.py

Github https://github.com/saurater/django_rest_api_hello_world/blob/main/EmployeeApp/serializers.py

12.2 Insert the code below:

from rest_framework import serializers
from EmployeeApp.models import Departments,Employees

class DepartmentSerializer(serializers.ModelSerializer):
class Meta:
#Let Django know the Class/Table you’d like to serialize
model=Departments
#List all the fields you’d like to work with
fields=('DepartmentId','DepartmentName')

class EmployeeSerializer(serializers.ModelSerializer):
class Meta:
#Let Django know the Class/Table you’d like to serialize
model=Employees
#List all the fields you’d like to work with
fields='EmployeeId','EmployeeName','Department','DateOfJoining','PhotoFileName')

13. API Methods

Time to enable the user to retrieve (GET), POST, update (PUT) or DELETE information across applications. This is achieved by creating Python functions (DEF) that check the request.method. Django calls such functions VIEWS.

Please change the views.py file as follows —

Github https://github.com/saurater/django_rest_api_hello_world/blob/main/EmployeeApp/views.py

#import crsf to be able to allow other domains to access our API Methods
from django.views.decorators.csrf import csrf_exempt
from rest_framework.parsers import JSONParser
from django.http.response import JsonResponse

from EmployeeApp.models import Departments,Employees
from EmployeeApp.serializers import DepartmentSerializer,EmployeeSerializer

from django.core.files.storage import default_storage

@csrf_exempt
def departmentApi(request,id=0):
if request.method==’GET’:
departments = Departments.objects.all()
departments_serializer=DepartmentSerializer(departments,many=True)
return JsonResponse(departments_serializer.data,safe=False)
elif request.method==’POST’:
department_data=JSONParser().parse(request)
departments_serializer=DepartmentSerializer(data=department_data)
if departments_serializer.is_valid():
departments_serializer.save()
return JsonResponse(“Added Successfully”,safe=False)
return JsonResponse(“Failed to Add”,safe=False)
elif request.method==’PUT’:
department_data=JSONParser().parse(request)
department=Departments.objects.get(DepartmentId=department_data[‘DepartmentId’])
departments_serializer=DepartmentSerializer(department,data=department_data)
if departments_serializer.is_valid():
departments_serializer.save()
return JsonResponse(“Updated Successfully”,safe=False)
return JsonResponse(“Failed to Update”)
elif request.method==’DELETE’:
department=Departments.objects.get(DepartmentId=id)
department.delete()
return JsonResponse(“Deleted Successfully”,safe=False)

@csrf_exempt
def employeeApi(request,id=0):
if request.method==’GET’:
employees = Employees.objects.all()
employees_serializer=EmployeeSerializer(employees,many=True)
return JsonResponse(employees_serializer.data,safe=False)
elif request.method==’POST’:
employee_data=JSONParser().parse(request)
employees_serializer=EmployeeSerializer(data=employee_data)
if employees_serializer.is_valid():
employees_serializer.save()
return JsonResponse(“Added Successfully”,safe=False)
return JsonResponse(“Failed to Add”,safe=False)
elif request.method==’PUT’:
employee_data=JSONParser().parse(request)
employee=Employees.objects.get(EmployeeId=employee_data[‘EmployeeId’])
employees_serializer=EmployeeSerializer(employee,data=employee_data)
if employees_serializer.is_valid():
employees_serializer.save()
return JsonResponse(“Updated Successfully”,safe=False)
return JsonResponse(“Failed to Update”)
elif request.method==’DELETE’:
employee=Employees.objects.get(EmployeeId=id)
employee.delete()
return JsonResponse(“Deleted Successfully”,safe=False)

@csrf_exempt
def SaveFile(request):
file=request.FILES[‘file’]
file_name=default_storage.save(file.name,file)
return JsonResponse(file_name,safe=False)

14. APP’s URL’s Settings

Now we need to let Django know hot to route the URL’s / HTTP’s requests to our views / functions. In order to achieve that, please create the urls.py file in the EmployeeApp folder and change it as follows:

Github https://github.com/saurater/django_rest_api_hello_world/blob/main/EmployeeApp/urls.py

Note: In Django 4.0, url is replaced by re_path, that’s why it is quite important to use the libs versions suggested in this tutorial.

from django.conf.urls import url
from EmployeeApp import views

from django.conf.urls.static import static
from django.conf import settings

urlpatterns=[
url(r’^department$’,views.departmentApi),
url(r’^department/([0–9]+)$’,views.departmentApi), #for id. With or without ID, we are routing to the save function

url(r’^employee$’,views.employeeApi),
url(r’^employee/([0–9]+)$’,views.employeeApi),

url(r’^employee/savefile’,views.SaveFile)
]+static(settings.MEDIA_URL,document_root=settings.MEDIA_ROOT)

APP urls.py

15. Project URL’s Settting

Finally, we need to let the application urls.py filleknow how to route the incoming requests to your app. Just include the line below to the urlpatterns section.

Github https://github.com/saurater/django_rest_api_hello_world/blob/main/DjangoAPI/urls.py

url(r’^’, include(‘EmployeeApp.urls’)),

Project urls.py

17. Running your Application

To run your application, just type up:

python3 manage.py runserver

runserver
Voilá… it works

To test all 4 API Methods, please use Postman Desktop

www.postman.com

Please Like, Subcribe and leave your comments

--

--