Introduction to API development using Django REST framework with Example

Django REST framework is  a best toolkit to create an API
It supports both ORM and Non-ORM data sources.
It can support regular function based view and class based views.

1) Installation of Django REST framework.

pip install djangorestframework

2) Add 'rest_framework'  in 'INSTALLED_APPS'

settings.py

INSTALLED_APPS = (
    ...
    'rest_framework',
    ...
)

3) configure the Django REST framework with 'REST_FRAMEWORK

This framework already contains some default configurations though we can override them like below

settings.py


REST_FRAMEWORK = {
    ....
    'DEFAULT_AUTHENTICATION_CLASSES': (
        'rest_framework.authentication.BasicAuthentication',
        'rest_framework.authentication.SessionAuthentication',
    ),
    ....
}

Now, we are ready to use the Django REST framework. It is very similar to the Django.

Now create your app and add it to INSTALLED_APPS in settings.py. consider the below code for example. we are writing both function and class based views. You can use function based or class based based on your comfort.

models.py

from django.contrib.auth.models import AbstractBaseUser, PermissionsMixin
GENDER_CHOICES = (
    ('Male', 'Male'),
    ('Female', 'Female'),
    ('Other', 'Other')
)

class User(AbstractBaseUser, PermissionsMixin):
    first_name = models.CharField(max_length=100)
    last_name = models.CharField(max_length=100)
    email = models.EmailField(unique=True)
    username = models.CharField(max_length=100, blank=True, null=True)
    is_active = models.BooleanField(default=True)
    is_staff = models.BooleanField(default=False)
    dob = models.DateField(null=True)
    phone = models.CharField(max_length=20, null=True)
    gender = models.CharField(choices=GENDER_CHOICES, max_length=6)
    address = models.TextField()
    password = models.CharField(maxlength=255)

    def __str__(self):
        return self.email

urls.py

from django.conf.urls import url
from . import views

urlpatterns = [
    url(r'^user/create/$', views.UserCreateView.as_view(), name="user_create"),
    url(r'^users/list/$', views.UsersListView.as_view(), name="users_list"),
    url(r'^users/(?P<pk>\d+)/detail/$', views.UserDetailView.as_view(), name="user_detail"),
    url(r'^users/(?P<pk>\d+)/update/$', views.UserUpdateView.as_view(), name="user_update"),
    url(r'^users/(?P<pk>\d+)/delete/$', views.UserDeleteView.as_view(), name="user_delete"),    
]

1. User Create View

serializer for validation( similar to django forms)

serializers.py

from rest_framework import serializers
from .models import GENDER_CHOICES, User

# normal serializer [similar to forms.Form]
class UserSerializer(serializers.Serializer):
    first_name = serializers.CharField(max_length=100)
    last_name = serializers.CharField(max_length=100)
    email = serializers.EmailField()
    username = serializers.CharField(max_length=100)
    dob = serializers.DateField()
    phone = serializers.CharField(max_length=20)
    gender = serializers.ChoiceField(choices=GENDER_CHOICES)
    address = serializers.TextField()
    password = serializers.CharField(max_length=255) 
    # is called if we save serializer if it do not have an instance
    def create(self, validated_data):
       password = validated_data.pop("password")
       user = User.objects.create(**validated_data)
       if password:
           user.set_password(password)
           user.save()
       return user
    # is called if we save serializer if it have an instance
    def update(self, instance, validated_data):
       password = validated_data.pop("password")
       instance.__dict__.update(validated_data)
       if password:
           instance.set_password(password)
       instance.save()
       return instance

# model serializer [similar to forms.ModelForm]
class UserSerializer(serializers.ModelSerializer):
    class Meta:
        model = User
        fields = ("first_name", "last_name", "email", "username", "dob", "phone", "gender", "address")

generic_views.py
from rest_framework import generics
from .serilizers import  UserSerializer

class UserCreateView(generics.CreateAPIView):
    serializer_class = UserSerializer

function_views.py

from rest_framework.decorators import api_view
from rest_framework.response import Response
from .serilizers import UserSerializer


@api_view(["POST"])
def create_user(request):
    serializer = UserSerializer(request.data)
    if serializer.is_valid():
        serializer.save()
        return Response({"message": "User created"}) 
    else:
        data = {
          "error": True,
          "errors": serializer.errors,          
        }
        return Response(data)        

2. User Detail View

generic_views.py


from rest_framework import generics
from .serilizers import  UserSerializer

class UserDetailView(generics.RetrieveAPIView):
    queryset = User.objects.all()
    serializer_class = UserSerializer

function_views.py

from rest_framework.decorators import api_view
from rest_framework.response import Response
from .serilizers import UserSerializer
from .models import *

@api_view(["GET"])
def user_details(request, pk):
    user = User.objects.get(id=pk)
    serializer = UserSerializer(user)
    return Response(serializer.data)

3. User Update View 

generic_views.py

from rest_framework import generics
from .serilizers import  UserSerializer

class UserUpdateView(generics.RetrieveUpdateAPIView):
    queryset = User.objects.all()
    serializer_class = UserSerializer

function_views.py

from rest_framework.decorators import api_view
from rest_framework.response import Response
from .serilizers import UserSerializer
from .models import *

@api_view(["GET", "PUT"])
def user_update(request, pk):
    user = User.objects.get(id=pk)
    if request.method == "PUT":
        serializer = UserSerializer(user, data=request.data)
        if serializer.is_valid():
            serializer.save()
            return Response(serializer.data)
        else:
            return Response({"error": serializer.errors, "error": True}) 
    serializer = UserSerializer(user)
    return Response(serializer.data)


3. User List View 

generic_views.py


from rest_framework import generics
from .serilizers import  UserSerializer

class UsersListView(generics.ListAPIView):
    queryset = User.objects.all()
    serializer_class = UserSerializer

function_views.py

from rest_framework.decorators import api_view
from rest_framework.response import Response
from .serilizers import UserSerializer
from .models import *

@api_view(["GET"])
def users_list(request):
    users = User.objects.all()
    serializer = UserSerializer(users, many=True)
    return Response(serializer.data)
4. User DeleteView

generic_views.py

from rest_framework import mixins
from.models import *

class UserDeleteView(mixins.RetrieveModelMixin, mixins.DestroyModelMixin):
    queryset = User.objects.all()
    
    def get(self, request, *args, **kwargs):
        return self.destroy(request, *args, **kwargs)

function_views.py

from .models import *
from rest_framework.decorators import api_view
from rest_framework.response import Response

def delete_user(request, pk):
    user = get_object_or_404(User, id=pk)
    user.delete()
    return Response({"message": "Deleted"})
    
for more implementation details please visit http://www.django-rest-framework.org/#tutorial

To Know more about our Django CRM(Customer Relationship Management) Open Source Package. Check Code

Posted On 26 January 2017 By MicroPyramid


Need any Help in your Project?Let's Talk

Latest Comments
Related Articles
Sending emails using sendgrid on heroku for a Django App

Integrate Sendgrid API to your Heroku app to deliver simplified emails like any notification emails, user signups etc.

Continue Reading...
Extract data from PDF and all Microsoft Office files in python

The quick way to get/extract text from PDFs in Python is with the Python library "slate". Slate is a Python package that simplifies the process ...

Continue Reading...
Implement search with Django-haystack and Elasticsearch Part-1

Haystack works as search plugin for django. You can use different back ends Elastic-search, Whose, Sorl, Xapian to search objects. All backends work with same ...

Continue Reading...
open source packages

Subscribe To our news letter

Subscribe and Stay Updated about our Webinars, news and articles on Django, Python, Machine Learning, Amazon Web Services, DevOps, Salesforce, ReactJS, AngularJS, React Native.
* We don't provide your email contact details to any third parties