AzoftCase StudiesHow To Create Web Services Using Django REST Framework

How To Create Web Services Using Django REST Framework

By Dmitriy Kuragin on April 16, 2013

When developing web applications, we often use Django technology and today I will tell you why we like it. To keep things short for the busy reader, I can summarize in a few words: simplicity and productivity. For those interested in the details, read below. We'll go step-by-step through the process of creating a simple web service using Django.

What is Django?

Django is a high-level Python Web framework for rapid development of dynamic web applications. Django was originally developed for serving news-oriented sites and was consequently designed to solve two main problems:

  • Fast and intensive website content creation and management;
  • High standards for web application quality.

The result of these design considerations is a well-established framework that greatly increases development productivity and allows to split the responsibilities of writing Python code and designing HTML.

One of Django design principles is the principle of ‘don't repeat yourself’ (DRY) aimed at reducing repetition of code.

What is Django REST Framework?

As the name implies, Django REST framework is a lightweight framework for Django that makes it possible to leverage Representational State Transfer (REST) technology in your application. This framework provides a way to access databases in a uniform way and create a RESTful API for your website in the meantime.

Its key features are:

  • Simple, accessible, displays resources using class-based views.
  • Supports ModelResources and input data validation.
  • Pluggable parsers, views, authorization - everything is customizable.
  • Changing content type is possible via HTTP headers access.
  • Optional support for forms with validation.

Using Django REST Framework

Okay, let's create a simple app to demonstrate the speed of development when using Django REST Framework. I'm going to skip the Python and Django setup part. There is more than enough information about that available online.

To start developing we need to create project. This is done by the command:

django-admin.py startproject blogpost

This command creates the project directory and generates some boilerplate code inside. Next, we need to define the models for our database tables. To do this, edit models.py in the following way:

from django.db import models  

class BlogPost(models.Model):
        title = models.CharField(max_length=128)
        content = models.TextField()
        created = models.DateTimeField(auto_now_add=True)  

class Comment(models.Model):
        blogpost = models.ForeignKey(BlogPost, editable=False,
                                    related_name='comments')
        comment = models.TextField()
        created = models.DateTimeField(auto_now_add=True)

In this tutorial we have two tables: BlogPost and Comment. The real names of these tables in the database will be different, but we don't care about that because we're accessing them through the ORM. The next step is to create a resource file called resource.py with the following contents:

from django.core.urlresolvers import reverse
from djangorestframework.resources import ModelResource
from blogpost.models import BlogPost, Comment  

class BlogPostResource(ModelResource):
        model = BlogPost
        fields = ('created', 'title', 'content', 'url', 'comments',)
        ordering = ('-created',)  

        def comments(self, instance):
                return reverse('comments', kwargs={'blogpost':instance.id})  

class CommentResource(ModelResource):
        model = Comment
        fields = ('created', 'comment', 'url', 'blogpost',)
        ordering = ('-created',)  

        def blogpost(self, instance):
                return reverse('blog-post', kwargs={'id':instance.blogpost.id})  

We just created the resource models that will be used by the views. We specified the fields to output and provided methods for the generated fields (which contain links in this example).

It is necessary to add URLs to urls.py. An URL is created by associating a regular expression with the corresponding view and resource model:

from django.conf.urls.defaults import patterns, url
from djangorestframework.views import ListOrCreateModelView, InstanceModelView
from blogpost.resources import BlogPostResource, CommentResource  

urlpatterns = patterns('',
    url(r'^$', ListOrCreateModelView.as_view(resource=BlogPostResource), name='blog-posts-root'),
    url(r'^(?P[^/]+)/$', InstanceModelView.as_view(resource=BlogPostResource), name='blog-post'),
    url(r'^(?P[^/]+)/comments/$', ListOrCreateModelView.as_view(resource=CommentResource),
name='comments'),
    url(r'^(?P[^/]+)/comments/(?P[^/]+)/$', InstanceModelView.as_view(resource=CommentResource)),
)

Don't forget to add the database description in settings.py:

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.sqlite3', # Add 'postgresql_psycopg2', 'mysql', 'sqlite3' or 'oracle'.
        'NAME': 'database.sqlite3',                      # Or path to database file if using sqlite3.
        'USER': '',                      # Not used with sqlite3.
        'PASSWORD': '',                  # Not used with sqlite3.
        'HOST': '',                      # Set to empty string for localhost. Not used with sqlite3.
        'PORT': '',                      # Set to empty string for default. Not used with sqlite3.
    }
} 

We use sqlite3 for simplicity's sake. Make sure the list of applications in settings.py looks like the list below:

INSTALLED_APPS = (
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.sites',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'djangorestframework',
    'blogpost',
    # Uncomment the next line to enable the admin:
    # 'django.contrib.admin',
    # Uncomment the next line to enable admin documentation:
    # 'django.contrib.admindocs',
)

This code tells the framework that our application called Blogpost is included in the project and djangorestframework is used to enable output templates for our test. Finally, let's run the following command:

python manage.py syncdb

The command will create the database and all the necessary tables and it's time to run the project. We can test the service API directly in the browser:

python manage.py runserver 0.0.0.0:8000

What functionality does the service provide?

  • GET request with the path http://localhost:8000 will return a list of posts (if there are any).
  • POST request with the path http://localhost:8000 and data fields such as title and content will create new posts.
  • If there is a post with a known id (for example id=3), then a GET request with the path http://localhost:8000/3/comments will return a list of comments to this post.
  • POST request with the path http://localhost:8000/3/comments and the required data fields will create a new comment.
  • OPTIONS request with the path http://localhost:8000/3/comments or http://localhost:8000/ will return the data format in use.
  • To change a post with a known id (for example id=5), just send PUT with the path http://localhost:8000/5/ and the required data fields. This applies to comments as well.
  • All of this can be tested directly in a browser, because the browser always passes an HTTP header "Accept: text/html". This header tells the framework to use textual templates for representing data.

Django is really a huge topic and I'll probably return to it again at some point. The Django website has a documentation section with lots of useful information. In this post I just wanted to get you started and to show how website creation may become a simple and practical matter with this amazing framework.

VN:F [1.9.22_1171]
Rating: 4.7/5 (7 votes cast)
VN:F [1.9.22_1171]
Rating: +3 (from 3 votes)
How To Create Web Services Using Django REST Framework, 4.7 out of 5 based on 7 ratings

Content created by Dmitriy Kuragin