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.
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’, }
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.
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.
File “C:UsersindiaDesktopTaskprojectenvTaskAPITaskviews.py”, line 33,
in RegistrationView
model = User
NameError: name ‘user’ is not defined
I am getting this error
Import the User or it won’t work
from django.contrib.auth.models import User