Python Django Rest Framework Drf Tutorial

Written by

in

Are you ready to turn your Django projects into powerful, scalable web APIs? In this step‑by‑step tutorial we’ll explore the Django REST Framework (DRF)—the most popular toolkit for building RESTful services with Python and Django. From setting up a clean development environment to deploying a production‑ready API, you’ll learn the essential concepts, best practices, and code snippets that will accelerate your journey from beginner to confident DRF developer.

What Is Django REST Framework?

Django REST Framework is an open‑source library that extends Django’s capabilities, providing a robust set of tools for creating RESTful APIs. It handles serialization, authentication, permissions, pagination, and more, while staying true to Django’s “batteries‑included” philosophy. Because DRF is built on top of Django’s ORM and request/response cycle, you can reuse your existing models and views, making the transition from a traditional web app to an API seamless.

Setting Up the Development Environment

1. Install Python and create a virtual environment

# Verify Python version (>=3.9 recommended)
python3 --version

# Create and activate a virtual environment
python3 -m venv drf-env
source drf-env/bin/activate  # On Windows use `drf-env\Scripts\activate`

2. Install Django and DRF

# Upgrade pip first
pip install --upgrade pip

# Install Django and Django REST Framework
pip install django djangorestframework

3. Optional: Install useful extensions

  • django-filter – for powerful query‑parameter filtering.
  • drf-yasg – to generate interactive Swagger/OpenAPI documentation.
  • pytest-django – for streamlined testing.

Creating a New Django Project

Start by scaffolding a fresh Django project named myapi and an app called books. The app will host a simple library catalog API.

# Create project and app
django-admin startproject myapi
cd myapi
python manage.py startapp books

# Register the app and DRF in settings.py
# myapi/settings.py
INSTALLED_APPS = [
    # default Django apps …
    'rest_framework',
    'books',
]

Building Your First API with DRF

Define the Model

In books/models.py we’ll create a Book model with a few useful fields.

from django.db import models

class Book(models.Model):
    title = models.CharField(max_length=200)
    author = models.CharField(max_length=100)
    published_date = models.DateField()
    isbn = models.CharField(max_length=13, unique=True)
    price = models.DecimalField(max_digits=6, decimal_places=2)

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

Create a Serializer

Serializers translate model instances into JSON (or other formats) and validate incoming data.

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

class BookSerializer(serializers.ModelSerializer):
    class Meta:
        model = Book
        fields = '__all__'  # Expose all model fields

Write a ViewSet

ViewSets combine the logic for list, create, retrieve, update, and delete operations into a single class.

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

class BookViewSet(viewsets.ModelViewSet):
    """
    API endpoint that allows books to be viewed or edited.
    """
    queryset = Book.objects.all()
    serializer_class = BookSerializer

Configure URLs with Routers

DRF’s DefaultRouter automatically generates the standard routes for a ViewSet.

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

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

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

Finally, include the app’s URLs in the project’s root URL configuration.

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

urlpatterns = [
    path('admin/', admin.site.urls),
    path('api/', include('books.urls')),  # All DRF endpoints under /api/
]

Advanced Topics

Authentication and Permissions

Secure your API by enabling authentication schemes and fine‑grained permission classes.

  • Token Authentication – Simple token‑based auth for mobile or SPA clients.
  • JWT (JSON Web Tokens) – Stateless, scalable tokens using djangorestframework-simplejwt.
  • Session Authentication – Leverages Django’s built‑in session framework (good for internal tools).

Example permission setup in settings.py:

REST_FRAMEWORK = {
    'DEFAULT_AUTHENTICATION_CLASSES': [
        'rest_framework.authentication.TokenAuthentication',
        'rest_framework.authentication.SessionAuthentication',
    ],
    'DEFAULT_PERMISSION_CLASSES': [
        'rest_framework.permissions.IsAuthenticatedOrReadOnly',
    ],
}

Pagination

Large result sets can be split into manageable pages. DRF offers several pagination styles.

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

Clients can now request /api/books/?page=2 to retrieve the second page of results.

Filtering and Search

Enhance the API with dynamic query parameters using django-filter and DRF’s built‑in search filter.

# books/views.py (add to BookViewSet)
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.SearchFilter, filters.OrderingFilter]
    filterset_fields = ['author', 'published_date']
    search_fields = ['title', 'author']
    ordering_fields = ['published_date', 'price']

Testing Your API

Automated tests keep your API reliable. DRF provides an APIClient that works like the Django test client but understands JSON payloads.

# books/tests.py
from rest_framework.test import APITestCase
from django.urls import reverse
from .models import Book

class BookAPITest(APITestCase):
    def setUp(self):
        self.book = Book.objects.create(
            title='Django for APIs',
            author='John Doe',
            published_date='2023-01-15',
            isbn='1234567890123',
            price='29.99'
        )
        self.list_url = reverse('book-list')  # auto‑generated by router

    def test_list_books(self):
        response = self.client.get(self.list_url)
        self.assertEqual(response.status_code, 200)
        self.assertEqual(len(response.data['results']), 1)

    def test_create_book(self):
        data = {
            'title': 'Advanced DRF',
            'author': 'Jane Smith',
            'published_date': '2024-05-10',
            'isbn': '9876543210987',
            'price': '39.99'
        }
        response = self.client.post(self.list_url, data, format='json')
        self.assertEqual(response.status_code, 201)
        self.assertEqual(Book.objects.count(), 2)

Deploying DRF Applications

When you’re ready to go live, follow these production‑ready steps:

  1. Use a dedicated WSGI server such as gunicorn or uvicorn (for ASGI).
  2. Serve static files with whitenoise or a CDN.
  3. Secure the API with HTTPS (Let’s Encrypt) and proper CORS settings (django-cors-headers).
  4. Database optimization – enable connection pooling (e.g., pgbouncer for PostgreSQL).
  5. Environment variables

Comments

Leave a Reply

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