The Beautifully Simple Django REST Framework


Responsive image

It was about one year back that I absolutely fell in love with the simplicity, utterly well laid out structure and the comprehensive documentation of Django. It is just silly how easily you can learn the framework, and build a production ready application within days. To quote the Django team itself; "Django is a high-level Python Web framework that encourages rapid development and clean, pragmatic design. Built by experienced developers, it takes care of much of the hassle of Web development, so you can focus on writing your app without needing to reinvent the wheel. It’s free and open source." Anyhow, this is not about Django itself, but rather, just as impressive Django REST Framework

Sticking to the basic principles that make Django what it is, the REST Framework has its own well written documentation, ease of implementation and cummunity support, amoungst the many conveniences that come with it. Without further adieu, let's get down to an example.

Context: 

Implementing a commenting module in Vue.js, on this very Blog (Github) built in Django, where Vue will talk to the backend with the help of the API. Implementation of Vue will be a whole other story, which I shall get into on a differnt day. But for now, let me focus on setting up the most basic version of the API.

Assuming the basic Django project and app are already set up, let's look at the model we are going to expose to the API:

Assuming models are imported in the models.py file (from django.db import models)

class Comment(models.Model):

    article = models.ForeignKey(Article, default=None, on_delete=models.CASCADE)

    name = models.CharField(max_length=50)

    email = models.EmailField(max_length=50, default=None, blank=True, null=True)

    comment = models.TextField()

    # Return Comment

    def __str__(self):

        return str(self.comment)

Run makemigrations and migrate the changes to the database from the project directory

python3 manage.py makemigrations

python3 manage.py migrate

Assuming the model is imported and defined in the app's admin.py file (admin.site.register(models.Comment)), you would be able to view the newly created model in Django Admin

Now, given the model is working without any issues, let me get down to REST API business;

Get started by installing djangorestframework via pip

pip install djangorestframework (while virtualenv is active, or pip3 install djangorestframework instead)

Next we add djangorestframework to the INSTALLED_APPS in settings.py

INSTALLED_APPS = [

    # Add your apps here to enable them

    'django.contrib.admin',

    'django.contrib.auth',

    'django.contrib.contenttypes',

    'django.contrib.sessions',

    'django.contrib.messages',

    'django.contrib.staticfiles',

    'rest_framework',

]

Next step of the process would be to initiate the Serializers. Since the purpose of this post is to showcase how easy it is to set up a REST API in Django, I will not be getting into the technicalities of Serializers. However, please feel free to read through the official documentation

We import the model and create a Serializer Class (Classes will have to be defined for each model we require to be accessed through the API) within the serializers.py file which we create inside the app directory. Within the Serializer Class, a Meta Class is defined and the model which needs to be accessed through the API is called upon. Then we define the fields we require. When defining the Serializer Class, we pass the particular Serializer we are interested in, as the parameter for the Class. In this instance we are calling upon the ModelSerializer from rest_framework serializers we just imported. The ModelSerializer has the ability to serve both POST and GET request. And the following is the only bit of code that is required. More reading about ModelSerializers here.

# serializers.py

from rest_framework import serializers

from . import models

class CommentSerializer(serializers.ModelSerializer):

    class Meta:

        model = models.Comment

        fields = ('id', 'article', 'name', 'email', 'comment')

Once the Serializer Class is defined, we move towards the views. In the app's views.py file we define a view class as follows (yes, it's a class based view). Before we do this though, we make some imports. First, from rest_framework we import viewsets (again, more reading material on viewsets and routers here). In most cases viewsets is the default way to go over views. But that doesn't mean they work always. Hence, it is best to go through the official documentation to understad when to be using what. Finally we import the serializers and the models we just created. We pass ModelViewSet from the imported viewsets as the argument to the Class. Within the Class, we define the queryset. A Queryset is an API that comes with Django that is used for running DataBase queries, instead of executing direct SQL queries. In this instance, since we are calling all the objects within the Comment table we created above; queryset = models.Comment.objects.all(). Next we define the serializer_class variable and assign the CommentSerializer in serializers we created above.

from rest_framework import viewsets

from . import serializers

from . import models

# Comments API

class CommentView(viewsets.ModelViewSet):

    queryset = models.Comment.objects.all()

    serializer_class = serializers.CommentSerializer

Next, We move onto urls. Within the app's urls.py file, first we import path and include from django.urls. Next we import the views created above and from the rest_framework, routers (more info here). Before setting the urlpatterns, we need to define the API routers, which will be taking care of the url routing for the API

# API Routers

router = routers.DefaultRouter()

router.register('comment', views.CommentView)

First we define a router variable and assign the DefaultRouter Class from routers we imported, which automatically creates the API root view for us. Next we register the router by passing a url parameter (in our case 'comment') as well as the CommentView Class we created in the views.py file.

Next step is to define the urlpatterns. Considering the usual scenario, if we just want to access a single model through the API, our urlpattern would look something like this; path('comments/', include(router.urls), name='comment_api'). Hence, if we were to access the web interface that comes with the djangorestframework or if we were to use a tool like Postman, the URL would look something like this; localhost:55768/comments/comment (given that we set the path in the urlpattern as 'comments/' and that we specify a url parameter 'comment' when registering the router). Since we have passed the CommentView when registering the router above, all we have to do in the urlpattern is to include the router urls; include(router.urls)

urlpatterns = [

    path('comments/', include(router.urls), name='comment_api'),

]

And Wa-Lah! That's it. We have created a REST API. Maybe in its most basic form, but a functioning REST API nevertheless. The sole purpose of this was to showcase the beautiful beast that is, the Django REST Framework. Following along on the official documentation is highly recommended. And Django FTW! :D

Aug. 1, 2019, 5:16 a.m. by - Lesith