Working with APIs is important for most web developers. From extending other services for your app to providing resources for other apps and services, APIs are essential to modern web systems for application-to-application communication.
API, an acronym for Application Programming Interface is a means by which the client-side interacts with the server-side to respond to the request of the user. It is a protocol that establishes how components of software communicate together.
In this tutorial, we shall go through the procedure of creating a REST API with Django and a PostgreSQL database for a customer management app. We shall set up a Django app with Django Rest Framework. Also, we will install PostgreSQL and connect it with our API. Besides, we shall perform CRUD operations (GET
, POST
, PUT
and DELETE
) on the API.
The objective of this tutorial is to create a RESTful API with CRUD capabilities on the database. We shall set up the Django REST framework, create the views and corresponding URL patterns for the APIs and
In detail, we shall go through the following content:
- What is Django
- What is a RESTful API
- What is Django Rest Framework
- What are CRUD operations
What is PostgreSQL
Setting up Django Rest Framework
Setting up PostgreSQL
Creating up a Postgres database
Connecting the Postgres database with the API
Creating Views for the CRUD Operations
Creating corresponding URL patterns for the views
Prerequisites
- Have
Python
andpip
package manager installed - Have experience creating Django apps
- Have basic knowledge of Python programming
- Have basic experience using the command line
What is Django?
Django is an open-source Python framework for building high-performance web applications. It works by the Model-View-Controller design. A notable benefit of the framework is that it enables you to build websites with speed without re-inventing the wheel.
What is a REST API?
RESTful API is an architectural standard for APIs that request data using HTTP. The data can be used to create, update, read, and delete resources. REST is an acronym for representational state transfer and, it uses HTTP to request data from a particular URL and, it returns the data in different formats such as JSON, HTML, etc.
What is Django Rest Framework
Django REST framework (DRF) is an extensive and versatile toolkit for building APIs for the web. Not only is it widely used, but it is also very customizable.
What are CRUD operations?
CRUD refers to the four basic operations - Create, Read, Update and Delete - used in relational database systems.
CRUD enables the basic functionalities of creating, reading, updating, and deleting resources in a REST environment. The CRUD operations are usually mapped to standard HTTP methods - POST for creating, GET for reading, PUT for updating, and DELETE for deleting respectively.
From a database management perspective, the following explains how the CRUD operations work.
- CREATE: INSERT to create a new database record
- READ: SELECT to retrieve data from a database table
- UPDATE: UPDATES a record based on the specified primary key
- DELETE: DELETES a row in a database table
What is PostgreSQL?
PostgreSQL is a free and open-source relational database system. It provides the developer with extensibility and scalability. It works with a lot of programming languages and all major operating systems such as Windows, macOS, and Linux. We will use PostgreSQL as our database for the CRUD app we will build.
Installing PostgreSQL
You can install PostgreSQL with the following command in the terminal.
sudo apt-get update
sudo apt-get install python-pip python-dev libpq-dev postgresql postgresql-contrib
On macOS, you can install posgresql
in the terminal
with brew
:
brew install postgresql
Now, you may start up postresql
after its installation with the following command.
brew services start postgresql
If you use a Windows machine, you can download a compatible PostgreSQL installer from the official website of PostgreSQL.
Creating a Database
As part of the installation, PostgreSQL already created a user, postgres
by default for carrying out administrative responsibilities. We shall change to the user to create our database and new user.
sudo su - postgres
psql
gives us access to the Postgres interactive terminal where we can use the PostgreSQL queries.
psql
Now, we shall create a database for this project. Always make sure to create a separate database for each project you work on.
CREATE DATABASE mydb;
In the above command, we have used the CREATE
command in SQL to create our database which we named mydb
. We also ended the line with a semi-colon which comes after every command in SQL.
Creating a Database User
Now, we shall create a database user for our database. We will call the user myuser
. Replace password
with a strong password below.
CREATE USER myuser WITH PASSWORD 'password';
Let us now grant access rights to our new user to enable it to work on the database.
GRANT ALL PRIVILEGES ON DATABASE mydb TO myuser;
We can then exit the current user's shell session and get back to the postgres
user's session
\q
Now, let us leave the PostgreSQL interactive terminal back to the terminal.
exit
Installing Django and Setting up a Django Project
When working with Django apps, always create new Django projects in isolated environments with virtual environment packages like virtualenv
. Virtual environments help us to work with different versions of Python and other packages with different projects we have on our machine. Let us get the virtualenv
package which we shall use to create our virtual environment
sudo pip install virtualenv
Then, let us create a folder to house our projects and change directory into the new folder.
mkdir myproject && cd myproject
Inside the new folder, we will create the virtual environment for our project.
virtualenv env
The above command provides us a duplicate of Python and some other libraries in an isolated environment.
We will activate the virtual environment so we can use it in our project.
source env/bin/activate
The terminal should look like below. The name of the virtual environment will be in brackets preceding the line to show that the virtual environment has been activated.
(env) user@host:_
Going forward, we will install Django and set up our Django app inside the virtual environment.
pip install django djangorestframework psycopg2
We installed the following packages:
-
Django
: the Django package that allows us to work with the Django framework and create Django apps - Django Rest Framework: this toolkit gives us the features to create and use RESTful APIs with Django
-
psycopg2
: PostgreSQL package that connects our app to PostgreSQL
Now, we shall create a Django project with the django-admin
command.
django-admin startproject crm_project
cd
into the crm-project
directory and cd
into the sub-directory, crm-project
. We need to add the rest_framework
into the settings.py
file so it will be active in our project. Let us add it inside the INSTALLED_APPS
list:
INSTALLED_APPS = [
...
'rest_framework', #new
]
Setting up Django Database Configuration
We have created a PostgreSQL
database and a Django project. Now, we shall configure our Django project to use the PostgreSQL database.
Inside the settings.py
file of the project, you will see the DATABASES
section. It looks like the following:
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.sqlite3',
'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
}
}
We need to change the SQLite database configuration to the PostgreSQL
database that we created. Therefore, replace the DATABASES
code with the following:
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.postgresql_psycopg2',
'NAME': 'myproject',
'USER': 'myuser',
'PASSWORD': 'password',
'HOST': 'localhost',
'PORT': '',
}
}
Creating a Django app
Let us create an app in our Django project using manage.py
file in the root directory of the project. It allows us to work with Django in various ways such as creating apps, creating database tables from models, running the inbuilt server, etc. Whenever you want to run the manage.py
file, ensure that you are at the root directory where manage.py
exists,
python manage.py startapp customer
If you check the directory, a new sub-directory, customer
has been created. Let us add the new customer
app to the INSTALLED_APPS
list in the settings.py
file of our crm-project
.
INSTALLED_APPS = [
...
'rest_framework',
'customer', #new
]
If you cd
into customer, you would see that it has its models.py
and views.py
files.
We shall create models for the customer
app. Open the models.py
file of the customer
app, replace the content in it with the following code.
from django.db import models
class Customer(models.Model):
name = models.CharField("Name", max_length=240)
email = models.EmailField()
created = models.DateField(auto_now_add=True)
def __str__(self):
return self.name
The Customer
class in the above code extends from Django's Model class. CharField
, EmailField
,and DateField
are appropriate data types for the respective fields.
At this point, we will create database columns with the fields of our models through the process of migration. We will use the manage.py
file to apply the migrations.
python manage.py makemigrations
Then,
python manage.py migrate
Creating a REST API with Django Rest Framework
We shall build our API on Django Rest Framework. We shall be dealing with views, serializers, and URL endpoints. The endpoints are attached to the views which fetch the responses to web requests.
Serializers help with translating between JSON, XML, and native Python objects. Create a new file in the customer
directory and name it serializers.py
. Input the following code into it.
from rest_framework import serializers
from .models import Customer
class CustomerSerializer(serializers.ModelSerializer):
class Meta:
model = Customer
fields = ['pk', 'name', 'email', 'created']
The ModelSerializer
in the code above helps to serialize data for Customer
objects.
Now, we shall extend the GenericAPIViews
that come shipped with Django Rest Framework to create our views. Add the following code inside the views.py
of the customer
app.
...
from django.shortcuts import render
from .models import Customer
from rest_framework import generics
from .serializers import CustomerSerializer
class CustomerCreate(generics.CreateAPIView):
# API endpoint that allows creation of a new customer
queryset = Customer.objects.all(),
serializer_class = CustomerSerializer
class CustomerList(generics.ListAPIView):
# API endpoint that allows customer to be viewed.
queryset = Customer.objects.all()
serializer_class = CustomerSerializer
The above code enables us to use the CustomerCreate
view to create a new customer object, and the CustomerList
view will be used to list all the customers in the database.
Should in case we want to check for a single customer, we can add a CustomerDetail
view as follows:
...
class CustomerDetail(generics.RetrieveAPIView):
# API endpoint that returns a single customer by pk.
queryset = Customer.objects.all()
serializer_class = CustomerSerializer
We will include a view for the Update
action,
...
class CustomerUpdate(generics.RetrieveUpdateAPIView):
# API endpoint that allows a customer record to be updated.
queryset = Customer.objects.all()
serializer_class = CustomerSerializer
Let us add a view for the DELETE operation,
...
class CustomerDelete(generics.RetrieveDestroyAPIView):
# API endpoint that allows a customer record to be deleted.
queryset = Customer.objects.all()
serializer_class = CustomerSerializer
Now, create a new urls.py
file in the customer
directory and add the following code to it.
from django.urls import include, path
from .views import CustomerCreate, CustomerList, CustomerDetail, CustomerUpdate, CustomerDelete
urlpatterns = [
path('create/', CustomerCreate.as_view(), name='create-customer'),
path('', CustomerList.as_view()),
path('<int:pk>/', CustomerDetail.as_view(), name='retrieve-customer'),
path('update/<int:pk>/', CustomerUpdate.as_view(), name='update-customer'),
# path('delete/<int:pk>/', CustomerDelete.as_view(), name='delete-customer')
]
Each of the endpoints handles a particular HTTP method. The first endpoint handles the POST
method for CREATE operation. The second and third endpoints handle the GET
method for READ operations. The fourth endpoint handles the PUT
method for UPDATE operation while the last endpoint handles the DELETE
operation.
Notwithstanding, we still need to point the root urls.py
file to the urls.py
file of the customer
app. Let us go back to the crm_project
sub-directory and open the urls.py
file there. We will then include the customer
app endpoints.
from django.contrib import admin
from django.urls import path, include #new
urlpatterns = [
path('admin/', admin.site.urls),
path('customer/', include('customer.urls')), #new
]
The file already contained the urlpattern
for the Django-admin app which gives us administrator capabilities.
Django ships with an inbuilt server that could be used for testing purposes. We will run our application now through the server with the following command:
python manage.py runserver
Let us go to the URL http://127.0.0.1:8000/customer on the browser and we shall the interface of the Browsable API. Browsable API comes with REST Framework and allows us to interact with our API in the absence of a client-side app. We can visit each of the routes earlier defined in the urlpatterns
of our customer
app and perform the CRUD operations.
The Browsable API looks like the following for the customer-create endpoint at http://127.0.0.1:8000/customer/create
Conclusion
Well-done! We have learned how to set up a Rest API with Django connected to a PostgreSQL database. You can get the full code of the tutorial project here.
This tutorial helped us to build a RESTful API with the Django REST framework. We also learned how to set up PostgreSQL for a Django project. We used the command-line to create PostgreSQL databases and users. We connected the PostgreSQL database to a basic Django customer management application and added CRUD functionalities to the API.
With what we have learned, we should be able to create APIs in our web projects. We would also be able to learn more about API development. Thanks for your time. Kindly ask questions and share your ideas and suggestions.
Top comments (3)
While following this tutorial I've hit a problem when my tests would not have permissions to create a db for tests. I needed to add additional privileges on my user.
Here is a relevant snippet from the django docs: docs.djangoproject.com/en/3.2/topi...
And here are some instructions how to do this in posgresql: dba.stackexchange.com/questions/33...
For this tutorial it would be:
(within postgresql shell)
ALTER USER myuser CREATEDB;
Thanks for the detail walk thru and sample project to explain REST api using Django.
Just one small typo: Within DB settings - change the db name to 'NAME': 'mydb'. Remaining all working like a charm :)
Oh, my pleasure