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.
Make a project from a template
Use the code below to create an environment for further development.
$ 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 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
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 project/manage.py makemigrations core
Now to apply them, do this:
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
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 project/manage.py createsuperuser
Go to the admin url (ensure your development server is up):
Congratulations! Without writing much code at all, go take a look at your brilliant and free functionality.
If your company is hiring a Python developer, check out this Python test prepared by our professionals. It will allow you to identify the best talents very easily!
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:
$ 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
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
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
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:
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 “child” url router, where
Listing of project/apps/core/urls.py
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
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:
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/:
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.Django REST Framework Tutorial: Step by Step Guide with Demo and Source CodeClick To Tweet
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.
Yuri Kriachko is head of a Python/Django company, 7WebPages.
Like the article? Share it please!
It will REALLY help us to make more content here.