Converting a Django App to a REST API

2
16733

This article demonstrates how easy it is to convert a Django app into a REST API using the REST framework. The underlying assumption here is that the reader’s machine has a working version of Python and Python-pip.

Django is a well-known Web framework, which allows developers to develop ORM-based apps at a fast pace. If you don’t have Django installed on your system, use pip install Django on a terminal. It will install Django on your system.

Once Django is installed, let’s create a project, within which we will create a contacts app. Open a terminal or command prompt and execute the following command [refer to Figure 2]:

django-admin startproject myproject

cd myproject

django-admin startapp contacts

Open the myproject directory and you can see the structure shown in Figure 3.

Open models.py in the contacts directory and create a class Contact to represent the contact:

from django.db import models

# Create your models here.

class Contact(models.Model):

firstname = models.CharField(max_length=100)

lastname = models.CharField(max_length=100, null=True, blank=True)

address = models.TextField(max_length=100)

city = models.CharField(max_length=100)

state = models.CharField(max_length=100)

country = models.CharField(max_length=100)

home_phone = models.IntegerField(null=True, blank=True)

work_phone = models.IntegerField(null=True, blank=True)

home_other = models.IntegerField(null=True, blank=True)

work_other = models.IntegerField(null=True, blank=True)

mobile_prim = models.IntegerField()

mobile_seco = models.

IntegerField(null=True, blank=True)

Open settings.py in the myproject directory and add contacts in the installed app (refer to Figure 4).

In settings.py, at the end you can see databases that show where the database and table will be created. For this example, we will use SQLite3 as the database. To create a contacts table, execute the following command:

python manage.py makemigrations
Figure 1: Installing Django using Pip
Figure 2: Creating a project and app

This will create the migrations script. You can see that the migrations directory is created in the contacts directory with 0001_initial.py. Now, using the migrate command, create the table. It will create some other tables also.

python manage.py migrate

You can see the db.sqlite3 file in the myproject directory. Our app is ready, but still has no view that will generate any output. We can use Django templates to create a view, but can omit that section as we want a REST based interface for contacts. The next section will explore how to convert this app to a REST API.

Figure 3: Project and app directory structure
Figure 4: settings.py in the myproject directory

Why REST?

By using REST we ensure that our application can be accessed from anywhere and have any front-end. Let’s suppose we want to create a website using the latest technology like React or Angular, and also a mobile app or hybrid mobile app. However, if the website already exists and we want to create only a mobile app or React based app, we need to modify and return JSON instead of HTML. Instead of creating two different types of back-end logic to return HTML, JSON or some other format, we can expose our application as a REST API, which is for any client to consume and display it in the way it is capable of. Any client requesting the resource will get JSON as output, and will decide how to parse and display data.

For converting the application to a REST API, we need to use the rest_framework and perform the following steps.

  • Open a terminal or command prompt and execute the following command:
pip install djangorestframework
  • Open settings.py in the myproject directory, and add rest_framework in INSTALLED_APPS.
  • Create new files named serializers.py, views.py and urls.py in the contacts directory.

For any model to be exposed as REST we need to create a serializer class in serializer.py. We will create the ContactSerializer class with all the fields. Open serializer.py and add the following code to it:

from rest_framework import serializers

from models import Contact

class ContactSerializer(serializers.ModelSerializer):

class Meta:

model = Contact

fields = ‘__all__’

We need to specify URLs and views for the file. First, let’s create a view with the get and post methods. The get method will return all data in JSON format, and the post method will save the data after validating it. This can be extended to use the delete and put logic also. Open the views.py file in the contacts directory and add the following code:

from rest_framework import status

from rest_framework.decorators import api_view

from rest_framework.response import Response

from models import Contact

from serializers import ContactSerializer

@api_view([‘GET’, ‘POST’])

def contact_list(request):

“””

// List all snippets, or create a new snippet.

“””

if request.method == ‘GET’:

contacts = Contact.objects.all()

serializer = ContactSerializer(contacts, many=True)

return Response(serializer.data)

elif request.method == ‘POST’:

serializer = ContactSerializer(data=request.data)

if serializer.is_valid():

serializer.save()

return Response(serializer.data, status=status.HTTP_201_CREATED)

return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

We need to specify URLs to reach this view. Open urls.py in the myproject directory, where we will include the contacts view for processing.

from django.conf.urls import include, url

from django.contrib import admin

urlpatterns = [

# Examples:

# url(r’^$’, ‘myproject.views.home’, name=’home’),

# url(r’^blog/’, include(‘blog.urls’)),

url(r’^admin/’, include(admin.site.urls)),

url(r’^contacts/’, include(‘contacts.urls’)),

]

Open urls.py in the contacts directory, which will point to the view we created in views.py in this directory.

from django.conf.urls import include, url

from django.contrib import admin

from contacts import views

urlpatterns = [

# Examples:

# url(r’^$’, ‘myproject.views.home’, name=’home’),

# url(r’^blog/’, include(‘blog.urls’)),

url(r’^api/’, views.contact_list),

]

Now that we have done that, contacts/api will call our view contact_list and display all data from contacts. To test this, open a terminal and start the server using the following command:

python manage.py runserver

Open a browser with the URL localhost:8000/contacts/api and it will display what is shown in Figure 7.

Figure 5: Output of makemigrations command
Figure 6: Running the migrate command
Figure 7: Output of the first rest API

As we have no records, the get section displays no data. In the post section, add data in JSON format as shown in Figure 8, and press the Post button.

Our views post portion will be executed and data will be inserted in SQLite3. The page will get reloaded to display the record (Figure 9).

If we are creating a REST API, then get, post, put and delete are commonly used. Creating the views with a function for all models with all methods can be a tedious job. Instead of the function base view, we can create a class base view by inheriting the generics view to provide common functionality. Change views.py as follows:

from rest_framework import status

from rest_framework.decorators import api_view

from rest_framework.response import Response

from models import Contact

from serializers import ContactSerializer

from rest_framework import generics

class ContactList(generics.ListCreateAPIView):

queryset = Contact.objects.all()

serializer_class = ContactSerializer

class ContactDetail(generics.RetrieveUpdateDestroyAPIView):

queryset = Contact.objects.all()

serializer_class = ContactSerializer

Change urls.py in the contacts directory to point to the class base view as shown below:

from django.conf.urls import include, url

from django.contrib import admin

from contacts import views

urlpatterns = [

# Examples:

# url(r’^$’, ‘myproject.views.home’, name=’home’),

# url(r’^blog/’, include(‘blog.urls’)),

url(r’^api/’, views.ContactList.as_view()),

]
Figure 8: Posting data
Figure 9: After posting data
Figure 10: HTML form for post

Refresh the page and you will see that the post section has a form like structure. You can use the raw format also, but a new form like structure is more elegant.

A lot more can be done in REST; this article is just to get things rolling.

2 COMMENTS

  1. HI Ashish,

    Read your article and its very useful for me. But i have doubt so can you help out me on that?
    Actually i m trying to develop one sample application in which i m using PostgreSql database.
    So can you tell me if i have already tables are generated in that database than i have to create model for that?
    if yes than how to save and fetch data from database with using Django rest framework API?
    if no than how to access that table objects and than save and fetch data from database with using Django rest framework API?

    Thanks in advance.

LEAVE A REPLY

Please enter your comment!
Please enter your name here