Python Django Rest Framework Drf Tutorial

Written by

in

Looking to turn your Django web applications into powerful, scalable APIs? The Django REST Framework (DRF) makes it effortless to build robust RESTful services with minimal boiler‑plate. In this step‑by‑step tutorial we’ll walk through everything you need to know—from setting up a clean development environment to deploying a production‑ready API—so you can start delivering data to mobile apps, single‑page front‑ends, or third‑party services in no time.

What is Django REST Framework?

Django REST Framework (often abbreviated as DRF) is a flexible, open‑source toolkit that extends Django’s core capabilities to support the creation of Web APIs. It provides:

  • Powerful Serializer classes for converting complex data types to JSON.
  • Class‑based ViewSet and generic views that reduce repetitive code.
  • Automatic URL routing via DefaultRouter.
  • Built‑in authentication, permissions, throttling, pagination, and content negotiation.
  • Comprehensive browsable API for rapid debugging.

Because DRF sits on top of Django, you retain all of Django’s strengths—ORM, admin, middleware—while gaining a modern API layer.

Setting Up the Development Environment

Prerequisites

Before diving in, make sure you have the following installed on your machine:

  1. Python 3.9+ (the latest stable release is recommended).
  2. pip, the Python package manager.
  3. virtualenv or python -m venv for isolated environments.
  4. Git (optional but useful for version control).

Creating a Virtual Environment

python -m venv drf-tutorial-env
source drf-tutorial-env/bin/activate   # On Windows use `drf-tutorial-env\Scripts\activate`
pip install --upgrade pip

Installing Django and DRF

pip install django djangorestframework

Verify the installation:

python -m django --version
# Should output something like 5.0.2

Creating a New Django Project

Run the standard Django start‑project command and create an app called api where our API logic will live.

django-admin startproject mysite
cd mysite
python manage.py startapp api

Next, register the app and DRF in mysite/settings.py:

INSTALLED_APPS = [
    # Default Django apps...
    'rest_framework',
    'api',
]

Building Your First API

Defining a Simple Model

Let’s create a Book model that stores basic bibliographic data.

# api/models.py
from django.db import models

class Book(models.Model):
    title = models.CharField(max_length=200)
    author = models.CharField(max_length=100)
    published = models.DateField()
    isbn = models.CharField(max_length=13, unique=True)

    def __str__(self):
        return f"{self.title} by {self.author}"

Run migrations to create the table:

python manage.py makemigrations api
python manage.py migrate

Serializers: Bridging Models and JSON

A serializer translates model instances into JSON and validates incoming data.

# api/serializers.py
from rest_framework import serializers
from .models import Book

class BookSerializer(serializers.ModelSerializer):
    class Meta:
        model = Book
        fields = ['id', 'title', 'author', 'published', 'isbn']

ViewSets: CRUD Operations in One Class

DRF’s ModelViewSet gives you a full set of create, retrieve, update, and delete (CRUD) actions with just a few lines.

# api/views.py
from rest_framework import viewsets
from .models import Book
from .serializers import BookSerializer

class BookViewSet(viewsets.ModelViewSet):
    queryset = Book.objects.all()
    serializer_class = BookSerializer

Routing with DefaultRouter

The router automatically generates URL patterns for the viewset.

# api/urls.py
from django.urls import path, include
from rest_framework.routers import DefaultRouter
from .views import BookViewSet

router = DefaultRouter()
router.register(r'books', BookViewSet)

urlpatterns = [
    path('', include(router.urls)),
]

Don’t forget to include the app’s URLs in the project’s root urls.py:

# mysite/urls.py
from django.contrib import admin
from django.urls import path, include

urlpatterns = [
    path('admin/', admin.site.urls),
    path('api/', include('api.urls')),  # <‑‑ API endpoint
]

Testing the API Locally

Start the development server and explore the browsable API at http://127.0.0.1:8000/api/books/:

python manage.py runserver

The interface lets you list books, add new entries, and edit or delete existing ones—all without leaving your browser.

Adding Authentication and Permissions

For production APIs you’ll want to restrict access. DRF ships with several authentication schemes; we’ll enable token authentication.

Install the token package

pip install djangorestframework-simplejwt

Configure settings

# mysite/settings.py
REST_FRAMEWORK = {
    'DEFAULT_AUTHENTICATION_CLASSES': (
        'rest_framework_simplejwt.authentication.JWTAuthentication',
    ),
    'DEFAULT_PERMISSION_CLASSES': (
        'rest_framework.permissions.IsAuthenticated',
    ),
}

Create token endpoints

# mysite/urls.py (add the following)
from rest_framework_simplejwt.views import (
    TokenObtainPairView,
    TokenRefreshView,
)

urlpatterns += [
    path('api/token/', TokenObtainPairView.as_view(), name='token_obtain_pair'),
    path('api/token/refresh/', TokenRefreshView.as_view(), name='token_refresh'),
]

Now, only users with a valid JWT can access /api/books/. You can further fine‑tune permissions per viewset by overriding permission_classes.

Pagination, Filtering, and Ordering

Large collections need efficient navigation. DRF makes pagination a one‑line configuration.

Enable pagination

# mysite/settings.py
REST_FRAMEWORK.update({
    'PAGE_SIZE': 10,
    'DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.PageNumberPagination',
})

Filtering and ordering

# api/views.py (add imports)
from django_filters.rest_framework import DjangoFilterBackend
from rest_framework import filters

class BookViewSet(viewsets.ModelViewSet):
    queryset = Book.objects.all()
    serializer_class = BookSerializer
    filter_backends = [DjangoFilterBackend, filters.OrderingFilter, filters.SearchFilter]
    filterset_fields = ['author', 'published']
    ordering_fields = ['title', 'published']
    search_fields = ['title', 'author']

Install the filter backend:

pip install django-filter

Now you can query /api/books/?author=Jane%20Austen&ordering=-published to get sorted results.

Automated Testing with Django’s Test Client

Writing tests guarantees that future changes won’t break your API.

# api/tests.py
from django.urls import reverse
from rest_framework import status
from rest_framework.test import APITestCase
from .models import Book
from django.contrib.auth.models import User
from rest_framework_simplejwt.tokens import RefreshToken

class BookAPITest(APITestCase):
def setUp(self):
self.user = User.objects.create_user(username='tester', password='secret')
refresh = RefreshToken.for_user(self.user)
self.client.credentials(HTTP_AUTHORIZATION=f'Bearer {refresh.access_token}')

self.book = Book.objects.create(
title='Pride and Prejudice',
author='Jane Austen',
published='1813-01-28',
isbn='1112223334445'
)

def test_list_books(self):
url = reverse('book-list') # auto‑generated by router
response = self.client.get(url)
self.assertEqual(response.status_code, status.HTTP_200_OK)
self.assertEqual(response.data['count'], 1)

def test_create_book(self):
url = reverse('book-list')
data = {
'title': 'Emma',
'author': 'Jane Austen',
'published': '1815-12-23',
'isbn':

Comments

Leave a Reply

Your email address will not be published. Required fields are marked *