Django RestApis example – GET/POST/PUT/DELETE requests to PostgreSQL database

django-restapi-postgresql-example-django-rest-framework-tutorial-feature-image

In this tutorial, we’re gonna look at way to create Django RestAPIs with Get/Post/Put/Delete requests to interact with PostgreSQL Database using Django REST Framework.

Related Post: Django RestApis CRUD Application with Angular 6 & PostgreSQL tutorial

Django RestApi example Overview

Goal

The project create a set of Rest-APIs for GET/POST/UPDATE/DELETE APIs:

  • GET /customers/: get all customers
  • GET /customers/[id]: get a customer by id
  • POST /customers/: save a customer
  • PUT /customers/update/[id]: update a customer by id
  • DELETE /customers/[id]: delete a customer by id

We will config the Project to work with PostgreSQL database.

Project structure

There are several folders and files in our Django project:

django-restapi-postgresql-example-django-rest-framework-tutorial-project-structure

customers/apps.py: declares CustomersConfig class (subclass of the django.apps.AppConfig) that represents our Django app and its configuration.
gkzRestApi/settings.py: configures settings for the Django project, including INSTALLED_APPS list with Django REST framework and Customers Application.
customers/models.py: defines Customer data model class (subclass of the django.db.models.Model).
migrations/0001_initial.py: is generated by makemigrations command, includes the code to create the Customer model, will be run by migrate to generate PostgreSQL database table for Customer model.
customers/serializers.py: declares CustomerSerializer class (subclass of rest_framework.serializers.ModelSerializer) for Customer instances to manage serialization to JSON and deserialization from JSON.
customers/views.py: contains methods to process HTTP requests and produce HTTP responses (using CustomerSerializer).
customers/urls.py: defines urlpatterns to be matched with request functions in the views.py.
gkzRestApi/urls.py: defines root URL configurations that includes the URL patterns declared in customers/urls.py.

Setup Django RestApi project

Install Django REST framework

Django REST framework works on top of Django and helps us to build RESTful Web Services flexibly. To install this package, run command:
pip install djangorestframework

Create RestApi project

Create Django project named gkzRestApi with command:
django-admin startproject gkzRestApi

django-restapi-postgresql-example-django-rest-framework-tutorial-create-project

Install Python PostgreSQL adapter

We have to install Python PostgreSQL adapter to work with PostgreSQL database.
In this tutorial, we use psycopg2: pip install psycopg2.

Setup PostgreSQL Database engine

Open gkzRestApi/settings.py and change declaration of DATABASES:

DATABASES = {
   'default': {
        'ENGINE': 'django.db.backends.postgresql',
        'NAME': 'testdb',
        'USER': 'postgres',
        'PASSWORD': '123',
        'HOST': '127.0.0.1',
        'PORT': '5432',
    }
}
Create Customers App

Run following commands to create new Django App named customers:
cd gkzRestApi
python manage.py startapp customers

django-restapi-postgresql-example-django-rest-framework-tutorial-create-project-app

Open customers/apps.py, we can see CustomersConfig class (subclass of the django.apps.AppConfig) that represents our Django app and its configuration:

from django.apps import AppConfig


class CustomersConfig(AppConfig):
    name = 'customers'
Add Django Rest framework & RestApi App to Django project

Open gkzRestApi/settings.py, find INSTALLED_APPS, then add:

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    # Django REST framework 
    'rest_framework',
    # Customers application 
    'customers.apps.CustomersConfig',
]

Implement Django RestApi App

Data Model
Create Data Model

customers/models.py

from django.db import models


class Customer(models.Model):
    name = models.CharField(max_length=70, blank=False, default='')
    age = models.IntegerField(blank=False, default=1)
    active = models.BooleanField(default=False)
Run initial migration for data model

Run following Python script:
python manage.py makemigrations customers

We can see output text:

Migrations for 'customers':
  customers\migrations\0001_initial.py
    - Create model Customer

It indicates that the customers/migrations/0001_initial.py file includes code to create Customer data model:

# Generated by Django 2.1.7 on 2019-02-18 03:37

from django.db import migrations, models


class Migration(migrations.Migration):

    initial = True

    dependencies = [
    ]

    operations = [
        migrations.CreateModel(
            name='Customer',
            fields=[
                ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
                ('name', models.CharField(default='', max_length=70)),
                ('age', models.IntegerField(default=1)),
                ('active', models.BooleanField(default=False)),
            ],
        ),
    ]

The generated code defines a subclass of the django.db.migrations.Migration. It has an operation for creating Customer model table. Call to migrations.CreateModel() method will create a table that allows the underlying database to persist the model.

Run the following Python script to apply the generated migration:
python manage.py migrate customers

The output text:

Operations to perform:
  Apply all migrations: customers
Running migrations:
  Applying customers.0001_initial... OK

Check PostgreSQL Database, now we can see that a table for Customer model was generated and it’s named customers_customer:

django-restapi-postgresql-example-django-rest-framework-tutorial-postgresql-table

Create Serializer class

We need a Serializer class for Customer instances to manage serialization to JSON and deserialization from JSON.

– This CustomerSerializer will inherit from rest_framework.serializers.ModelSerializer superclass.
ModelSerializer class automatically populates a set of default fields and default validators, we only need to specify the model class.

Now, under customers package, create serializers.py file:

from rest_framework import serializers 
from customers.models import Customer


class CustomerSerializer(serializers.ModelSerializer):

    class Meta:
        model = Customer
        fields = ('id',
                  'name',
                  'age',
                  'active')

Meta inner class declares 2 attributes:
model: specifies the model related to the serializer
fields: specifies a tuple of field names that we want to include in the serialization

Create API Views

Open customers/views.py file and declare two functions:
customer_list(): get list of customers, save a new customer
customer_detail(): get/update/delete customer by id

from django.shortcuts import render 
from django.http import HttpResponse
from django.http.response import JsonResponse
from django.views.decorators.csrf import csrf_exempt
from rest_framework.parsers import JSONParser 
from rest_framework import status

from customers.models import Customer
from customers.serializers import CustomerSerializer

@csrf_exempt
def customer_list(request):
    if request.method == 'GET':
        customers = Customer.objects.all()
        customers_serializer = CustomerSerializer(customers, many=True)
        return JsonResponse(customers_serializer.data, safe=False)
        # In order to serialize objects, we must set 'safe=False'

    elif request.method == 'POST':
        customer_data = JSONParser().parse(request)
        customer_serializer = CustomerSerializer(data=customer_data)
        if customer_serializer.is_valid():
            customer_serializer.save() 
            return JsonResponse(customer_serializer.data, status=status.HTTP_201_CREATED) 
        return JsonResponse(customer_serializer.errors, status=status.HTTP_400_BAD_REQUEST)


@csrf_exempt 
def customer_detail(request, pk):
    try: 
        customer = Customer.objects.get(pk=pk) 
    except Customer.DoesNotExist: 
        return HttpResponse(status=status.HTTP_404_NOT_FOUND) 
 
    if request.method == 'GET': 
        customer_serializer = CustomerSerializer(customer) 
        return JsonResponse(customer_serializer.data) 
 
    elif request.method == 'PUT': 
        customer_data = JSONParser().parse(request) 
        customer_serializer = CustomerSerializer(customer, data=customer_data) 
        if customer_serializer.is_valid(): 
            customer_serializer.save() 
            return JsonResponse(customer_serializer.data) 
        return JsonResponse(customer_serializer.errors, status=status.HTTP_400_BAD_REQUEST) 
 
    elif request.method == 'DELETE': 
        customer.delete() 
        return HttpResponse(status=status.HTTP_204_NO_CONTENT)
Route Urls to Views functions

Create urls.py in customers folder, now we will define urlpatterns to be matched with request functions in the views.py.

from django.conf.urls import url 
from customers import views 
 
urlpatterns = [ 
    url(r'^customers/$', views.customer_list),
    url(r'^customers/(?P[0-9]+)$', views.customer_detail),
]

Now we must include above URL patterns in root URL configurations.
Open gkzRestApi/urls.py, replace the code:

from django.conf.urls import url, include 
 
urlpatterns = [ 
    url(r'^', include('customers.urls')), 
]

Test results

To start the RestApi server, run command:
python manage.py runserver

– Save customer using POST HTTP method:

django-restapi-postgresql-example-django-rest-framework-tutorial-post-method

– Get list of customers using GET HTTP method:

django-restapi-postgresql-example-django-rest-framework-tutorial-get-all-method

– Get a customer by id using GET HTTP method:

django-restapi-postgresql-example-django-rest-framework-tutorial-get-method

– Update a customer by id using PUT HTTP method:

django-restapi-postgresql-example-django-rest-framework-tutorial-put-method

– Delete a customer by id using DELETE HTTP method:

django-restapi-postgresql-example-django-rest-framework-tutorial-delete-method

– Check PostgreSQL Database:

django-restapi-postgresql-example-django-rest-framework-tutorial-postgresql-table-result

Source Code

Django-RestApi-PostgreSQL

16 thoughts on “Django RestApis example – GET/POST/PUT/DELETE requests to PostgreSQL database”

  1. I抦 impressed, I need to say. Really hardly ever do I encounter a weblog that抯 both educative and entertaining, and let me inform you, you have got hit the nail on the head. Your thought is outstanding; the difficulty is one thing that not sufficient people are talking intelligently about. I am very pleased that I stumbled across this in my seek for something referring to this.

  2. It’s appropriate time to make some plans for the future and it is time to be happy. I have read this post and if I could I want to suggest you few interesting things or suggestions. Perhaps you could write next articles referring to this article. I want to read even more things about it!

  3. Youre so cool! I dont suppose Ive learn something like this before. So good to seek out anyone with some authentic thoughts on this subject. realy thank you for beginning this up. this website is one thing that is needed on the web, somebody with a bit originality. useful job for bringing something new to the web!

  4. Please let me know if you’re looking for a article author for your site. You have some really good articles and I feel I would be a good asset. If you ever want to take some of the load off, I’d love to write some articles for your blog in exchange for a link back to mine. Please blast me an e-mail if interested. Regards!

  5. Good ?I should certainly pronounce, impressed with your site. I had no trouble navigating through all the tabs as well as related information ended up being truly simple to do to access. I recently found what I hoped for before you know it at all. Reasonably unusual. Is likely to appreciate it for those who add forums or something, web site theme . a tones way for your client to communicate. Nice task..

  6. Great work! This is the kind of info that are supposed to be shared around the web. Shame on the seek engines for now not positioning this submit upper! Come on over and discuss with my site . Thanks =)

  7. Hi would you mind letting me know which hosting company you’re using? I’ve loaded your blog in 3 completely different internet browsers and I must say this blog loads a lot faster then most. Can you recommend a good internet hosting provider at a fair price? Thank you, I appreciate it!

  8. Hey! I just wanted to ask if you ever have any issues with hackers? My last blog (wordpress) was hacked and I ended up losing a few months of hard work due to no back up. Do you have any solutions to prevent hackers?

  9. Can I just say what a relief to search out somebody who really knows what theyre speaking about on the internet. You positively know find out how to carry an issue to light and make it important. Extra folks have to read this and understand this facet of the story. I cant consider youre not more fashionable because you definitely have the gift.

  10. There are some fascinating closing dates on this article but I don抰 know if I see all of them heart to heart. There’s some validity however I will take maintain opinion till I look into it further. Good article , thanks and we wish more! Added to FeedBurner as properly

  11. Have you ever thought about including a little bit more than just your articles? I mean, what you say is valuable and everything. But think about if you added some great pictures or videos to give your posts more, “pop”! Your content is excellent but with images and clips, this blog could definitely be one of the most beneficial in its field. Wonderful blog!

  12. Thanks for another magnificent article. Where else could anybody get that type of info in such a perfect way of writing? I have a presentation next week, and I am on the look for such info.

  13. Wow that was unusual. I just wrote an incredibly long comment but after I clicked submit my comment didn’t appear. Grrrr… well I’m not writing all that over again. Anyhow, just wanted to say wonderful blog!

Leave a Reply

Your email address will not be published. Required fields are marked *