Saturday, 17 February 2018

How to Make REST API in Django

Django API

Create REST API Using Core Django

Django is a popular web framework in the Python world for rapid development. Here we will learn, how to quickly make REST API (Representational State Transfer Application Programming Interface) using Django.

# Prerequisites:

Make sure, you have following things installed

# End Result:

We will make a small application that will keep track of all my friends with their respective details.
  • API to list all friends. 
  • API to get detail of a particular friend. 
  • API to add a friend in the list. 
  • API to delete a friend from the list. 

# Video Tutorial



After installing prerequisites, follow the below steps:

# Create Project

django-admin startproject my_project

Here the project name is my_project. This command will create a directory called my_project in your current working directory, with some pre populated directory and files. This directory is root directory for you project.

# Create App

cd my_project
python manage.py startapp my_app

The app name is my_app. You can create as many app you want inside one project. This command has created my_app directory inside the project's root directory.

# Database Creation and Setup

Let's use Sqlite as our database in this tutorial. If you are planning to use database other than Sqlite, you need to do appropriate settings in settings.py file of project.

To create tables, edit the models.py file of the app.

vim my_app/models.py

Here, we will create a table called, MyFriendList. To do this paste the following code in the opened file.
from django.db import models

class MyFriendList(models.Model):
    friend_name = models.CharField(max_length=200)
    mobile_no = models.IntegerField()


mobile_no = models.IntegerField() 

Table MyFriendList has two columns. First column is friend_name of char type and of max_length 200. Second column is mobile_no of integer type.

To actually create this Table in our database system, we need to run migrate commands. But before that, we need to add this app in our project. For this, open our project's config file.

vim my_project/settings.py 

Now, search for INSTALLED_APPS setting and edit it. It should look like this.

INSTALLED_APPS = [
    'my_app.apps.MyAppConfig',
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
]

Now, we will run migrate commands.

python manage.py makemigrations my_app
python manage.py migrate

First command, will make the migration files (a file that contains the equivalent SQL statements for Database) and second command will execute it. After executing migrate command, you should see migration of files that are not created by us. These are some required tables by Django.

# Create Views

Views are used to define business logic. Here we will make three views, to list, create and delete the friend list. First open the views.py file of my_app application.

vim my_app/views.py

Now paste the following code in the file:


from django.http import JsonResponse
from django.views import View
from django.views.decorators.csrf import csrf_exempt
from django.utils.decorators import method_decorator
import json

from .models import MyFriendList


class MyFriend(View):
    def get(self, request):
        friend_list = list(MyFriendList.objects.values())
        return JsonResponse(friend_list, safe=False) 

    # To turn off CSRF validation (not recommended in production)
    @method_decorator(csrf_exempt)
    def dispatch(self, request, *args, **kwargs):
        return super(MyFriend, self).dispatch(request, *args, **kwargs)

    def post(self, request):
        data = request.body.decode('utf8')
        data = json.loads(data)
        try:
            new_friend = MyFriendList(friend_name=data["friend_name"], mobile_no=data["mobile_no"])
            new_friend.save()
            return JsonResponse({"created": data}, safe=False)
        except:
            return JsonResponse({"error": "not a valid data"}, safe=False)

class MyFriendDetail(View):

    @method_decorator(csrf_exempt)
    def dispatch(self, request, *args, **kwargs):
        return super(MyFriendDetail, self).dispatch(request, *args, **kwargs)

    def get(self, request, pk):
        friend_list = {"friend": list(MyFriendList.objects.filter(pk=pk).values())}
        return JsonResponse(friend_list, safe=False)

    def put(self, request, pk):
        data = request.body.decode('utf8')
        data = json.loads(data)
        try:
            new_friend = MyFriendList.objects.get(pk=pk)
            data_key = list(data.keys())
            for key in data_key:
                if key == "friend_name":
                    new_friend.friend_name = data[key]
                if key == "mobile_no":
                    new_friend.mobile_no = data[key]
            new_friend.save()
            return JsonResponse({"updated": data}, safe=False)
        except MyFriendList.DoesNotExist:
            return JsonResponse({"error": "Your friend having provided primary key does not exist"}, safe=False)
        except:
            return JsonResponse({"error": "not a valid data"}, safe=False)

    def delete(self, request, pk):
        try:
            new_friend = MyFriendList.objects.get(pk=pk)
            new_friend.delete()
            return JsonResponse({"deleted": True}, safe=False)
        except:
            return JsonResponse({"error": "not a valid primary key"}, safe=False)

Let's understand the above code:

  • First, we imported the necessary modules and models for our application.
  • We have class MyFriend, containing get and post method that serves for GET and POST HTTP method respectively.
  • We have override the dispatch method of View class to turn off CSRF validation. However, its not recommended for production. We just turned it off for sake of simplicity.
  • get method of MyFriend class, lists all the friends.
  • post method of MyFriend class, allows to add new friend in the existing list.
  • After that, we have MyFriendDetail class, containing get, put and delete method that serves for GET, PUT and DELETE HTTP method respectively.
  • get method of MyFriendDetail class, takes one argument called "pk" (primary key) and provides the complete detail of the friend having that primary key.
  • put method of MyFriendDetail class, takes the "pk" to update the particular friend's details.
  • delete method of MyFriendDetail class, also takes the "pk" argument, and deletes the friend from the friend list having that pk as primary key. 

# Route Setup

Now, we need to configure endpoint or URL to access the app. First define route for my_app by editing project's urls.py file.

vim my_project/urls.py

Now, edit this file as follow:

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

urlpatterns = [
    path('friends/', include('my_app.urls')),
    path('admin/', admin.site.urls),
]

Here, we have defined the route friends/ for our app my_app. You can define different routes here for multiple apps.

Now define routes for the API of my_app. To do this create urls.py file inside my_app.

vim my_app/urls.py 

Now, paste following code inside the file:

from django.urls import path

from my_app.views import MyFriend, MyFriendDetail

urlpatterns = [
    path('', MyFriend.as_view()),
    path('<int:pk>/', MyFriendDetail.as_view()),
]

Let's understand the URL patterns

We have defined empty pattern for MyFreind class, so that our API will have structure like <server_name:port>/friends/. (Note: friends/ came from my_app application route that we defined in project wide urls.py)


For class MyFriendList, we have defined integer pattern for the key pk. Here API will have structure like <server_name:port>/friends/1/.

So, we are done with all the coding. We have model, views and urls in place. Now start the development server.

python manage.py runserver 

Output:
Performing system checks...

System check identified no issues (0 silenced).
February 17, 2018 - 18:57:06
Django version 2.0.2, using settings 'my_project.settings'
Starting development server at http://127.0.0.1:8000/
Quit the server with CONTROL-C.

Hurray! Our Django REST APIs are ready on http://127.0.0.1:8000/. Let's try it now.

I am using Postman app to hit the API.

# Add a friend in friend list.

API: /friends/
Method: POST
Data: {"friend_name": "abc", "mobile_no": 8968678990}



# Get the friend list.

API: /friends/
Method: GET





# Edit name of a friend

API: /friends/6/
Method: PUT
Data: {"friend_name": "xyz"}





# Fetch detail of a particular friend

API: /friends/6/
Method: GET



# Delete a friend from friend list:

API: /friends/6/
Method: DELETE






Whoa! We successfully tested the CRUD for my_app.


Next step is to learn deployment of Django application. For this checkout this tutorial.

1 comments:

  1. Thanks, it helped a lot. It's very useful to know, how the core django will works.

    ReplyDelete

 

Copyright @ 2013 Appychip.

Designed by Appychip & YouTube Channel