DEV Community

Cover image for Django Rest Framework with PostgreSQL: A CRUD Tutorial
entuziaz
entuziaz

Posted on

Django Rest Framework with PostgreSQL: A CRUD Tutorial

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 and pip 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
Enter fullscreen mode Exit fullscreen mode

On macOS, you can install posgresql in the terminal with brew:

brew install postgresql
Enter fullscreen mode Exit fullscreen mode

Now, you may start up postresql after its installation with the following command.

brew services start postgresql
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

psql gives us access to the Postgres interactive terminal where we can use the PostgreSQL queries.

psql
Enter fullscreen mode Exit fullscreen mode

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;
Enter fullscreen mode Exit fullscreen mode

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';
Enter fullscreen mode Exit fullscreen mode

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;
Enter fullscreen mode Exit fullscreen mode

We can then exit the current user's shell session and get back to the postgres user's session

\q
Enter fullscreen mode Exit fullscreen mode

Now, let us leave the PostgreSQL interactive terminal back to the terminal.

exit
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

Then, let us create a folder to house our projects and change directory into the new folder.

mkdir myproject && cd myproject
Enter fullscreen mode Exit fullscreen mode

Inside the new folder, we will create the virtual environment for our project.

virtualenv env
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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:_
Enter fullscreen mode Exit fullscreen mode

Going forward, we will install Django and set up our Django app inside the virtual environment.

pip install django djangorestframework psycopg2
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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
]
Enter fullscreen mode Exit fullscreen mode

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'),
    }
}
Enter fullscreen mode Exit fullscreen mode

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': '',
    }
}
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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
]
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

Then,

python manage.py migrate
Enter fullscreen mode Exit fullscreen mode

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']

Enter fullscreen mode Exit fullscreen mode

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

Enter fullscreen mode Exit fullscreen mode

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

Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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')
]
Enter fullscreen mode Exit fullscreen mode

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
]
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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

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.

Twitter | LinkedIn

Top comments (3)

Collapse
 
ilonajulczuk profile image
Justyna Ilczuk

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;

Collapse
 
thirukr profile image
thirukr • Edited

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 :)

Collapse
 
entuziaz profile image
entuziaz

Oh, my pleasure