Django is one of the most popular Python Web frameworks out there. With more than 50k stars on GitHub, it has a vast community of developers that can help you with any issues that you might face during development. Today, we’ll see just how easy it is to build a REST API with Django.

Django REST Framework

To build REST APIs, we shall use the Django REST Framework. This package is an addon to Django and it exists solely to make building APIs easy for developers.

Features of Django REST Framework (DRF):

  1. Browsable API: DRF provides a Web based GUI that enables you to browse your APIs. This GUI is a huge convenience and easily the best feature of DRF.
  2. Authentication Packages: DRF provides out of the box support for OAuth1 and OAuth2, saving you a ton of time in working out the details by yourself.
  3. Serialization: DRF supports serialization for ORM and Non-ORM type data into JSON format.

Let’s see how we can use DRF to build a robust REST API with Django.

Setup a New Django DRF Project

Let’s get started by creating a new directory for our project:

mkdir django-rest-api
cd django-rest-api

We’ll also create a new Python virtual environment to isolate our project’s dependencies from your local system.

python -m venv env
source env/bin/activate  # On Windows run `env\Scripts\activate`

After the previous step, your command line will be appended with (env):

(env) C:\codezen\django-rest-api-tutorial>

Install Django and Django REST Framework using pip:

pip install django
pip install djangorestframework

Create a new Django project and a single application:

django-admin startproject django_rest_api .
cd django_rest_api
django-admin startapp demo

After running the above command, your project structure should look like the following:

$ find .
.
./asgi.py
./demo
./demo/admin.py
./demo/apps.py
./demo/migrations
./demo/migrations/__init__.py
./demo/models.py
./demo/tests.py
./demo/views.py
./demo/__init__.py
./settings.py
./urls.py
./wsgi.py
./__init__.py

It might look unusual that we’re creating an application within a project, but this is required to avoid namespace related errors with Python modules.

In settings.py, add rest_framework to the INSTALLED_APPS variable:

INSTALLED_APPS = [
    ...
    'rest_framework',
]

In the same file, we’ll define the DRF related config. For now, we will just set the pagination size for our API responses.

REST_FRAMEWORK = {
    'DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.PageNumberPagination',
    'PAGE_SIZE': 10
}

Now run the migrations using the following command:

python manage.py migrate

The above command will generate the database tables related to admin and the default user model. For this demonstration, I’ll be using the default models. Also, keep in mind that we will use the default sqlite3 database in the tutorial. However, you can easily change it to MySQL by changing the default key in settings.py.

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.mysql',
        'NAME': 'dbname',
        'USER': 'root',
        'PASSWORD': '',
        'HOST': '127.0.0.1',
        'PORT': '',
    },
}

Create a Super Admin User

DRF comes bundled with a Super Admin module. Using the Super Admin account, you can manage other user models and also browse the API.

python manage.py createsuperuser --email sapnesh@codezen.io --username admin

Setup Serializers

Serializers are a mechanism to define how the API should return or format the responses of your models. Create a file named serializers.py in the demo folder and add the following code to it.

from django.contrib.auth.models import User, Group
from rest_framework import serializers

class UserSerializer(serializers.HyperlinkedModelSerializer):
    class Meta:
        model = User
        fields = ['url', 'username', 'email', 'groups']


class GroupSerializer(serializers.HyperlinkedModelSerializer):
    class Meta:
        model = Group
        fields = ['url', 'name']

In the above code, we define two classes, namely UserSerlializer and GroupSerializer. Each of these classes binds to a model (User and Group) and defines the fields that are to be allowed in API responses.

Create Viewsets for User and Group Model

Simply put, Viewsets are classes that define the actions for a model. For example, these can be list, create, get, update, and destroy. You can also call Viewsets as Controllers from an MVC architecture point of view.

Let’s define Viewsets for both the User and the Group model in views.py in the demo folder.

from django.contrib.auth.models import User, Group
from rest_framework import viewsets
from rest_framework import permissions
from django_rest_api.demo.serializers import UserSerializer, GroupSerializer


class UserViewSet(viewsets.ModelViewSet):
    """
    API endpoint that allows users to be viewed or edited.
    """
    queryset = User.objects.all().order_by('-date_joined')
    serializer_class = UserSerializer
    permission_classes = [permissions.IsAuthenticated]


class GroupViewSet(viewsets.ModelViewSet):
    """
    API endpoint that allows groups to be viewed or edited.
    """
    queryset = Group.objects.all()
    serializer_class = GroupSerializer
    permission_classes = [permissions.IsAuthenticated]

Note that we are not explicitly defining any actions here. Instead, we inherit the viewSets.ModelViewSet class, which has the default implementations and we only have to pass a queryset. This queryset contains all our User model objects.

Define Routes

It’s time to define our application routes for the user model. Add the following code to urls.py .

from django.contrib import admin
from django.urls import include, path
from rest_framework import routers
from django_rest_api.demo import views

router = routers.DefaultRouter()
router.register(r'users', views.UserViewSet)
router.register(r'groups', views.GroupViewSet)

# Wire up our API using automatic URL routing.
# Additionally, we include login URLs for the browsable API.
urlpatterns = [
    path('', include(router.urls)),
    path('api-auth/', include('rest_framework.urls', namespace='rest_framework'))
]

In the above code, we’re adding our two viewsets and Django will automatically create APIs for them.

Testing the API

Now let’s test our API. To do so, we can start the webserver using manage.py, this starts the server at http://127.0.0.1:8000. After that, we will use Postman to make API requests.

python manage.py runserver

Get All Users

We can submit a GET request to /users to get a list of all users:

GET_Users_ Django REST Framework

Create a New User

Make a POST request to /users/ to create a a new user:

POST_Users Django Rest Framework

Update a User

We can also update a user’s details by making a PUT request to the server with the user’s ID. In this case, the user with an ID of 1.

PUT_User Django Rest Framework

Delete User

You can also delete a User by providing their ID and making a DELETE request on the resource.

DELETE_User Django Rest Framework

That’s it! As you can see, the process is quite straightforward and easy to build a simple REST API with Django and Django REST Framework. If you have any doubts or questions, feel free to ask them in the comment section below. Also, the source code for the project used in this tutorial is in my Github repository.