Django – Setup Django REST framework

We have the Django welcome page working already.

 

I would like to create some REST services on that setup. We could make use of the Django REST framework.

Let’s keep working on our <project_root>/django_poc project to manage articles by REST. The example in this post are based on the Django REST framework quickstart tutorial. It’s good to go through all of them which could give you a more thorough idea on how the REST framework works.

1. Install the Django REST framework in your virtualenv.

pip install djangorestframework

 

2. Create a new app called articles.

python manage.py startapp articles

 

3. Configure the sqlite database in <project_root>/django_poc/settings.py.

# Database
# https://docs.djangoproject.com/en/1.6/ref/settings/#databases

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.sqlite3',
        'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
        'USER': '',
        'PASSWORD': '',
        'HOST': '',
        'PORT': '',
    }
}

 

4. Configure INSTALLED_APPS to include the Django REST framework as well as the newly created articles app. Also add the pagination setting of the REST framework.

# Application definition

INSTALLED_APPS = (
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'rest_framework',
    'articles',
)

# REST framework

REST_FRAMEWORK = {
    'PAGINATE_BY': 10
}

 

5. Setup the articles routes in <project_root>/django_poc/urls.py.

from django.conf.urls import patterns, include, url

from django.contrib import admin
admin.autodiscover()

urlpatterns = patterns('',
  url(r'^admin/', include(admin.site.urls)),
  url(r'^', include('articles.urls')),
)

 

6. Let’s create the Article model.
<project_root>/django_poc/articles/models.py

from django.db import models


# Create your models here.
class Article(models.Model):
  created = models.DateTimeField(auto_now_add=True)
  title   = models.CharField(max_length=100, blank=True, default='')
  body    = models.TextField()
  owner   = models.ForeignKey('auth.User', related_name='articles')

  class Meta:
    ordering = ('created',)

 

7. Since we have setup a new model, execute syncdb again to create the article table.

python manage.py syncdb

 

8. Create the serializer for interconverting the article and user instance and json.
<project_root>/django_poc/articles/serializers.py

from django.forms import widgets
from django.contrib.auth.models import User
from rest_framework import serializers
from articles.models import Article


class ArticleSerializer(serializers.ModelSerializer):
  owner = serializers.Field(source='owner.username')

  class Meta:
    model = Article
    fields = ('id', 'title', 'body', 'owner',)


class UserSerializer(serializers.HyperlinkedModelSerializer):
  # Inherit serializers.HyperlinkedModelSerializer to
  # hyperlink the articles to the correspongind page.
  articles = serializers.HyperlinkedRelatedField(many=True, view_name='article-detail')

  class Meta:
    model = User
    fields = ('id', 'username', 'articles')

 

9. Create the views by the Django REST framework ViewSet.
<project_root>/django_poc/articles/views.py

from rest_framework import permissions
from rest_framework import viewsets
from django.contrib.auth.models import User
from articles.models import Article
from articles.serializers import ArticleSerializer, UserSerializer
from articles.permissions import IsOwnerOrReadOnly


class ArticleViewSet(viewsets.ModelViewSet):
  """
  This viewset automatically provides `list`, `create`, `retrieve`,
  `update` and `destroy` actions.
  """
  queryset = Article.objects.all()
  serializer_class = ArticleSerializer
  permission_classes = (permissions.IsAuthenticatedOrReadOnly,
                        IsOwnerOrReadOnly,)

  def pre_save(self, obj):
    obj.owner = self.request.user


class UserViewSet(viewsets.ReadOnlyModelViewSet):
  """
  This viewset automatically provides `list` and `detail` actions.
  """
  queryset = User.objects.all()
  serializer_class = UserSerializer

 

10. Setup the views permissions.
<project_root>/django_poc/articles/permissions.py

from rest_framework import permissions


class IsOwnerOrReadOnly(permissions.BasePermission):
  """
  Custom permission to only allow owners of an object to edit it.
  """
  def has_object_permission(self, request, view, obj):
    # Read permissions are allowed to any request,
    # so we'll always allow GET, HEAD or OPTIONS requests.
    if request.method in permissions.SAFE_METHODS:
      return True

    # Write permissions are only allowed to the owner of the article.
    return obj.owner == request.user

 

11. Setup the routers for the articles app.
<project_root>/django_poc/articles/urls.py

from django.conf.urls import patterns, url, include
from articles import views
from rest_framework.routers import DefaultRouter

# Create a router and register our viewsets with it.
router = DefaultRouter()
router.register(r'articles', views.ArticleViewSet)
router.register(r'users', views.UserViewSet)

# The API URLs are now determined automatically by the router.
# Additionally, we include the login URLs for the browseable API.
urlpatterns = patterns('',
  url(r'^', include(router.urls)),
  url(r'^api-auth/', include('rest_framework.urls', namespace='rest_framework'))
)

 

12. Finally we can start the application.

python manage.py runserver 0.0.0.0:8000

 

13. Open the app in browser.
setup-django-rest-framework
 

14. You can log in and create new article on the article listing page.

15. Here are some curl commands for testing the API.

# GET by specifying the Accept header
curl http://127.0.0.1:8000/articles/ -H 'Accept: application/json'  # Request JSON
curl http://127.0.0.1:8000/articles/ -H 'Accept: text/html'         # Request HTML

# GET by format suffix
curl http://127.0.0.1:8000/articles/.json  # JSON suffix
curl http://127.0.0.1:8000/articles/.api   # Browsable API suffix (HTML)

# POST using form data
curl -X POST http://127.0.0.1:8000/articles/ -d "title=New Article" -d "body=Hello world" -u user:password

# POST using json
curl -X POST http://127.0.0.1:8000/articles/ -d '{ "title": "New Article", "body": "Hello world" }' -H "Content-Type: application/json" -u user:password

 

Done =)

Advertisements

3 thoughts on “Django – Setup Django REST framework”

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s