Click here to Skip to main content
15,036,441 members
Articles / Django
Technical Blog
Posted 9 Jan 2018

Tagged as

Stats

6.7K views
4 bookmarked

Django REST Framework Tutorial

Rate me:
Please Sign up or sign in to vote.
5.00/5 (2 votes)
9 Jan 2018CPOL4 min read
Django REST Framework tutorial

If you are working on a single-page application and you want it to have some persistence, it’s a really good idea to have a REST API. This way, you’ll be able to store your domain’s entities in the database. In this article, you will learn how to create a basic application with Django and Django REST framework. You can use this as a starting point, and then it’s quite easy to extend this project with different pluggable Django applications.

You can find a repository here and demo here. The animation below shows the automatically generated HTML interface of the API created in this tutorial:

ezgif.com-crop

Make a Project from a Template

Use the code below to create an environment for further development.

Python
$ mkdir drf-demo; cd drf-demo 
$ virtualenv .env 
$ pip install "Django >= 1.9, < 1.10" 
$ django-admin startproject project 
  --template=https://github.com/ambivalentno/django-skeleton/archive/master.zip 
$ mkdir log $ mkdir project/db

Now your environment is fully functional.

Next, start your development server with the following:

Python
$ python project/manage.py runserver

Finally, go to http://localhost:8000/. You will see a “Welcome, Django” message.

Define Some Models

Here, we want to model students that go to a university. So, let’s first define entity classes and their attributes. Every university has a name; and every student has a first name, last name and attends a single university (many-to-one relationship). To see a list of available fields, you can go to the Django manual for model fields.

Listing of project/apps/core/models.py

Python
from django.db import models

class University(models.Model):
    name = models.CharField(max_length=50)

    class Meta:
        verbose_name = "University"
        verbose_name_plural = "Universities"

    def __unicode__(self):
        return self.name

class Student(models.Model):
    first_name = models.CharField(max_length=50)
    last_name = models.CharField(max_length=50)
    university = models.ForeignKey(University)

    class Meta:
        verbose_name = "Student"
        verbose_name_plural = "Students"

    def __unicode__(self):
        return '%s %s' % (self.first_name, self.last_name)

Each Model here is related to a table in the database. As we don’t have these tables in the database yet, let’s create a rule to make them (in Django, these rules are called migrations):

Python
python project/manage.py makemigrations core

Now to apply them, do this:

Python
python project/manage.py migrate core

You will see a lot of SQL queries logged to the console, and that’s absolutely fine. Now you have a database structure defined and we are ready to put some data in it.

Enable the Admin Interface and Populate the Database

Django’s admin interface offers a visually convenient way to discover and edit database data. To enable it, add this to the project/apps/core/admin.py:

Listing of project/apps/core/admin.py

Python
from django.contrib import admin
from .models import University, Student

admin.site.register(University)
admin.site.register(Student)

Next, create an admin user (comand-line dialogue omitted, as it’s quite obvious):

Python
python project/manage.py createsuperuser

Go to the admin url (ensure your development server is up):

You can add universities here and students here.

Congratulations! Without writing much code at all, go take a look at your brilliant and free functionality.

Django REST framework-based API

Obviously, you cannot plug in anything unless you install it, so let’s install Django REST framework (or DRF) with pip:

Python
$ pip install djangorestframework

Next, you should add ‘rest_framework’ to the INSTALLED_APPS at the project/conf/base.py so that it’s available for Django process.

Write Some Model-based Serializers

To perform HTTP-based interaction, we have to define rules to convert Django models (python objects) to the json strings and vice versa. This is a serialization/deserialization task. So, let’s define some model-based serializers:

Listing of project/apps/core/serializers.py

Python
from rest_framework import serializers
from .models import University, Student

class UniversitySerializer(serializers.ModelSerializer):
    class Meta:
        model = University

class StudentSerializer(serializers.ModelSerializer):
    class Meta:
        model = Student

Of course, you can manually define your own serializers. As a reference, you can use DRF’s documentation or even some performance-oriented serializers.

Make a Quick viewset

A viewset is a set of views (controllers in traditional MVC terminology). If you take a look at the ModelViewSet code, you’ll see that there’s a lot of functionality automatically added there. You are able to create, view, edit and delete objects in your system (and database). It’s a full CRUD set with http as the interface protocol. Let’s configure two viewsets for our classes:

Listing of project/apps/core/views.py

Python
from rest_framework import viewsets
from .models import University, Student
from .serializers import UniversitySerializer, StudentSerializer

class StudentViewSet(viewsets.ModelViewSet):
    queryset = Student.objects.all()
    serializer_class = StudentSerializer

class UniversityViewSet(viewsets.ModelViewSet):
    queryset = University.objects.all()
    serializer_class = UniversitySerializer

Now we need to expose this logic to the outer space, which is done via url routers: we have to define mappings from http request addresses to the views (controllers).

To attach app-level urls to the general workflow – edit project/urls.py:

Python
from django.conf import settings
from django.conf.urls import url, include
from django.contrib import admin

urlpatterns = [
    url(r'^admin/', admin.site.urls),
    url(r'^api/', include('apps.core.urls', namespace='core')),
]

if settings.DEBUG:
    from django.conf.urls.static import static
    urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
    urlpatterns += static(settings.STATIC_URL, document_root=settings.STATIC_ROOT)

Here, we are rerouting all requests that have ‘api’ in the url to the apps.core.urls. Here’s a “childurl router, where:

Listing of project/apps/core/urls.py

Python
from django.conf.urls import url
from rest_framework import routers
from core.views import StudentViewSet, UniversityViewSet

router = routers.DefaultRouter()
router.register(r'students', StudentViewSet)
router.register(r'universities', UniversityViewSet)

urlpatterns = router.urls

At this moment, you’ve got a working API. Let’s check it out!

Look at the Browsable API

Go to the http://localhost:8000/api (demo url http://drf-demo.herokuapp.com/api) where you will see the browsable API:

rsz_screen_api_html

Next, go to http://localhost:8000/api/universities/ (demo link http://drf-demo.herokuapp.com/api/universities/) where you will see it’s possible to create new universities via POST requests with a simple form submission.

In case you want to view raw JSON – you can go to http://localhost:8000/api/universities/?format=json (demo link http://drf-demo.herokuapp.com/api/universities/?format=json). For students, it’s the same: http://localhost:8000/api/students/ (demo link http://drf-demo.herokuapp.com/api/students/)

Generate and Read Automatic Documentation with django-rest-swagger

We’ve already installed one Django application, via pip. Now install Django-rest-swagger and add it to the INSTALLED_APPS (‘rest_framework_swagger’). To expose it at the url routing level, edit core/urls.py this way:

Python
from django.conf.urls import url, include
from rest_framework import routers
from core.views import StudentViewSet, UniversityViewSet

router = routers.DefaultRouter()
router.register(r'students', StudentViewSet)
router.register(r'universities', UniversityViewSet)

urlpatterns = [
    url(r'^docs/', include('rest_framework_swagger.urls')),
]
urlpatterns += router.urls

As you can see here, we’ve used rest_framework_swagger to merge the API’s urls from the router and urls. You can check if it works at http://localhost:8000/api/docs/:

rsz_swagger

This way, you’re able to view the definitions of DELETE, PUT and PATCH commands differently from the default DRF browsable API. Also, you may find the “Try it” button convenient.

Summary

I hope this article helps you set up a REST API for your project. Remember, you can easily extend it, and if it’s hard for you – please, contact us.

Author 
Yuri Kriachko is head of a Python/Django company, 7WebPages.

The post appeared first on Tests4Geeks.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

Share

About the Author

Tests4Geeks is programming skill testing service.
Besides our main business, we also produce programming tutorials which allow readers to learn new tools and languages.

Comments and Discussions

 
-- There are no messages in this forum --