The Complete Magazine on Open Source

Use Django and REST frameworks to create simple API

SHARE
/ 3246 0

Jagno

This article is a short tutorial on how to create a simple TaskAPI with SQLite, which communicates over JSON and REST. We will use the Django Web and REST frameworks.

Nowadays, we live in a multi-platform world. Everyone has at least one computer, tablet, smartphone or smartwatch. Our little gadgets store and retrieve data. What a great opportunity this presents to touch billions of people with excellent applications, which even those without any computer knowledge can handle.

Whatever front-end you can think of, on whichever platform, you still need a way to store data. The back-end is the heart of every simple and complex application.

In this article, we will discuss how to create a simple TaskAPI with SQLite, which communicates over JSON and REST. We will use the Django Web and REST frameworks.

Virtual environment and project set-up
First of all, it is a good habit to set up a new Python virtual environment to quarantine the requirements from the rest of the system. You can install virtualenv and all the other requirements over PyPI.

I assume you have already installed Python 3.X and virtualenv.

$ mkdir Taskproject
$ cd Taskproject
$ virtualenv env
$ source env/bin/activate  # On Windows use ‘env\ Scripts\activate’

Now, we are in our virtual environment and every requirement we want to install will be placed inside the env folder. Let’s install the necessary requirements in specific versions via Pip.
In this article, we use Python 3.X, Django 1.9 and the Django REST framework 3.0.

-# Install Django and Django REST framework into the virtualenv
$ (env) pip install django
$ (env) pip install djangorestframework
# by default PIP install the latest version.
FIG 1---API End Points

Figure 1: API end points

FIG 2---Register API

Figure 2: Register user

Creating a Django project and app 

A Django project can manage multiple Django applications. We are going to create a project called TaskAPI, and an application called Task inside the TaskAPI project.

$ (env) django-admin.py startproject TaskAPI
$ (env) cd TaskAPI
$ (env) django-admin.py startapp Task

Adjusting the project settings

The settings are defined in the file /TaskAPI/settings.py. First, we have to add the installed apps.  For our application, we need to install the Task app along with the mandatory Django application, and the Django REST framework, rest_framework.

The installed apps are listed in the INSTALLED_APPS constant in setting.py.

INSTALLED_APPS = (
‘rest_framework’,
‘Task’,
)

Any global settings for a REST framework API are kept in a single configuration dictionary named REST_FRAMEWORK.

REST_FRAMEWORK = {
‘DEFAULT_MODEL_SERIALIZER_CLASS’:
‘rest_framework.serializers.ModelSerializer’,
}
FIG 3---List Task

Figure 3: List task

FIG 4---Create Task

Figure 4: Create task

Creating models

Let’s go back to the Task app in the folder Task and create the models we need in the file /Task/models.py. In order to define a Task model, we need to derive from the Model class. Let’s use User class of the standard authentication as a foreign key in the owner attribute.
We define an owner, task name, description of the task, a status and an attribute which stores the last time a model got updated.

from django.db import models
from django.contrib.auth.models import User
class TaskModel(models.Model):
    user = models.OneToOneField(User)
    task_name = models.CharField(max_length=100)
    task_description = models.TextField(max_length=200)
    status = models.BooleanField(default=False)
    date = models.DateTimeField(auto_now_add=True)

Initialising the database
We have to set up the database for storing data. In the default settings, an SQLite database with the required schema is automatically created with the following commands:

$ (env) python manage.py makemigrations
$ (env) python manage.py migrate

Creating serialisers

We’ll declare a serialiser that we can use to serialise and deserialise data that corresponds to TaskModel objects.

Let’s create a new module named Task/serializers.py that we’ll use for our data representations.
The ModelSerializer class provides a shortcut that lets you automatically create a Serializer class with fields that correspond to the Model fields.

from django.contrib.auth.models import User
from rest_framework import serializers
from .models import TaskModel
class TaskSerializer(serializers.ModelSerializer):
    user  = serializers.CharField(source=’user.username’,read_only=True)
    class Meta:
        model = TaskModel
        fields = (‘user’,’task_name’,’task_description’,’status’,’date’)
class RegistrationSerializer (serializers.ModelSerializer):
    password = serializers.CharField(write_only=True)
    def create(self, validated_data):
        user = User.objects.create(
            username = validated_data[‘username’]
        )
        user.set_password(validated_data[‘password’])
        user.save()
        return user
    class Meta:
        model = User
        fields = (‘username’,’password’)

We defined two serialiser classes TaskSerializer and RegistrationSerializer. TaskSerializer has the user as a read_only serialiser field, which references our logged in user or we can say a user who has permission to perform CRUD operations on the Task model.

RegistrationSerializer has a password field as a write_only because we don’t want to serialise the hashed password. We override the serialisers create() method in order to create a user instance.

FIG 5---Update and Delete Task

Figure 5: Update task

Adjusting the URL dispatcher
Now, let’s set up the URL dispatcher in the file /TaskAPI/urls.py. The URL dispatcher sets the URL routes to specific views in Django. A view handles logic and sends HTTP responses.

The REST framework adds support for automatic URL routing to Django, using the Routers.Django REST framework, which provides SimpleRouter, DefaultRouter and CustomRouters.

Let’s use SimpleRouter and URL patterns in this project for now.

We will implement TaskView for the creation, listing, deletion and updation of tasks and RegistrationView for user registration.

from django.conf.urls import include, url
from django.contrib import admin
from rest_framework import routers
from Task import views
 
router = routers.SimpleRouter()  
router.register(r’task’,views.TaskView,base_name=’task’) 
urlpatterns = [
    url(r’^’,include(router.urls)),
    url(r’^register’, views. RegistrationView.as_view(), name=’register’),
    url(r’^admin/’, include(admin.site.urls)),
    url(r’^api-auth/’, include(‘rest_framework.urls’,namespace=’rest_framework’)),
]

The explanation for various end points used in the code above is given below.

/task: We create a SimpleRouter object and register our view for automatic URL routing. This end point handles all CRUD operations related to the task object.

/register: This end point is defined for user registration. RegistrationView is Django class based views.

/api-auth: This is the built-in Django REST authentication end point.

Adding the views: RegistrationView and TaskView
First, we implement the TaskView. The following belongs to the file /Task/views.py. For TaskView, we intentionally use the REST framework’s viewsets.ModelViewSet, which will automatically create all the HTTP verbs end points for us. Let’s define the HTTP verbs GET, POST and PUT. Every user needs to be authenticated in order to access this end point; that’s why we set permission_classes as IsAuthenticated. We override a get_queryset method, so the GET method filters all to-dos by the logged-in user and just responds with the serialised data. In the POST method, we validate the incoming data with the TodoSerializer. If the incoming data is valid, we create a to-do object and save it. The method replies with the incoming data and the primary key ID.

from rest_framework import permissions,viewsets
from .models import TaskModel
from rest_framework.generics import CreateAPIView
from .serializers import TaskSerializer,RegistrationSerializer
 
class TaskView(viewsets.ModelViewSet):
    “”” Only Authenticate User perform CRUD Operations on Respective Task
    “””
    permission_classes = (permissions.IsAuthenticated,)
    model = TaskModel
    serializer_class = TaskSerializer
 
    def get_queryset(self):
        “”” Return tasks belonging to the current user “””
        queryset = self.model.objects.all()
        # filter to tasks owned by user making request
        queryset = queryset.filter(user=self.request.user)
 
        return queryset
 
    def perform_create(self, serializer):
        “”” Associate current user as task owner “””
        return serializer.save(user=self.request.user)

We use the perform_create method to associate the current user as the task owner, which is provided by the mixin classes, and provide easy overriding of the object save.

Now let’s handcraft RegistrationView, which lets unregistered users register. The following belongs to the file /Task/views.py:

class RegistrationView(CreateAPIView):
    “”” CreateAPIView have only POST method
    “””
    model = User
    serializer_class = RegistrationSerializer
    permission_classes = (permissions.AllowAny,)

We derive the RegistrationView from the CreateAPIView from the REST framework’s generic views. CreateAPIView supports only the POST HTTP verb, and we want to post the username and password into our database in order to create a user. Everyone, logged in or not, should be able to use this view; therefore, we set the permission_classes to an AllowAny. First, let’s validate the incoming data with the RegistrationSerializer. After validation, we can create the user.

Play with the browsable API 

Start the development server of your TaskAPI project. By default, this starts an HTTP server on port 8000.

$ (env) python manage.py runserver

Because the REST framework provides a browsable API, feel free to interact with the API through the Web browser at http://localhost:8000/.

Figures 2 to 5 show a few API end point tests while Figures 2 and 3 show POST/register and GET/task APIs, Figures 4 and 5 show POST/task and PUT/task/1 APIs.

In this article, you implemented a simple TaskAPI with Django and the Django REST framework, with basic authentications and permissions. We have now learned quite a lot about the Django REST framework, including how to implement a Web-browsable API which can return JSON for you, how to configure serialisers to compose and transform your data, and how to use class based views to extract boilerplate code.