Python Django Rest Framework Drf Tutorial

Written by

in

Welcome to the ultimate Python Django REST Framework (DRF) tutorial! Whether you’re a seasoned Django developer or just dipping your toes into API development, this guide will walk you through every essential step—from setting up your environment to building a production‑ready RESTful API. By the end, you’ll have a solid grasp of DRF’s core components, best practices, and how to deliver scalable, secure APIs that search engines love. Let’s dive in and transform your Django projects into powerful data‑driven services.

What Is Django REST Framework?

Django REST Framework is a flexible, modular toolkit for building Web APIs on top of the Django ecosystem. It abstracts away much of the boilerplate involved in serialization, request handling, and authentication, letting you focus on business logic. DRF is widely adopted because it integrates seamlessly with Django’s ORM, supports both function‑based and class‑based views, and provides a browsable API that’s perfect for debugging and documentation.

Core Concepts You Need to Know

  • Serializers: Convert complex Django model instances into native Python data types (and vice‑versa) for JSON, XML, or other formats.
  • ViewSets: Combine the logic for a set of related views (list, retrieve, create, update, delete) into a single class.
  • Routers: Automatically generate URL patterns for ViewSets, reducing manual routing work.
  • Authentication & Permissions: Control who can access your API and what actions they can perform.
  • Browsable API: An HTML interface that lets developers explore endpoints directly from a web browser.

Setting Up the Development Environment

Prerequisites

Before you start, make sure you have the following installed:

  • Python 3.9+ (preferably via pyenv or a virtual environment)
  • pip (Python package installer)
  • Git (optional, but recommended for version control)
  • A code editor such as VS Code or PyCharm

Installing Django and DRF

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

# Upgrade pip and install Django with DRF
pip install --upgrade pip
pip install django djangorestframework

Once installed, verify the versions:

python -c "import django, rest_framework; print('Django', django.get_version(), 'DRF', rest_framework.__version__)"

Building Your First API

1. Create a Django Project

django-admin startproject myproject
cd myproject

2. Create an App

python manage.py startapp blog

Don’t forget to add 'blog' and 'rest_framework' to INSTALLED_APPS in myproject/settings.py:

INSTALLED_APPS = [
    # default Django apps …
    'rest_framework',
    'blog',
]

3. Define a Model

In blog/models.py create a simple Post model:

from django.db import models

class Post(models.Model):
    title = models.CharField(max_length=200)
    content = models.TextField()
    created_at = models.DateTimeField(auto_now_add=True)

    def __str__(self):
        return self.title

4. Create a Serializer

Serializers translate model instances to JSON. Add blog/serializers.py:

from rest_framework import serializers
from .models import Post

class PostSerializer(serializers.ModelSerializer):
    class Meta:
        model = Post
        fields = ['id', 'title', 'content', 'created_at']

5. Build Views with ViewSets

In blog/views.py use a ModelViewSet to get CRUD operations for free:

from rest_framework import viewsets
from .models import Post
from .serializers import PostSerializer

class PostViewSet(viewsets.ModelViewSet):
    queryset = Post.objects.all().order_by('-created_at')
    serializer_class = PostSerializer

6. Register Routes with Routers

DRF routers automatically generate the URL conf. Edit myproject/urls.py:

from django.contrib import admin
from django.urls import path, include
from rest_framework import routers
from blog.views import PostViewSet

router = routers.DefaultRouter()
router.register(r'posts', PostViewSet)

urlpatterns = [
    path('admin/', admin.site.urls),
    path('api/', include(router.urls)),
    path('api-auth/', include('rest_framework.urls')),  # optional login UI
]

7. Migrate and Test

python manage.py makemigrations
python manage.py migrate
python manage.py runserver

Visit http://127.0.0.1:8000/api/posts/ in your browser. You’ll see the DRF browsable API, allowing you to list, create, and edit posts without writing any extra HTML.

Handling Authentication and Permissions

Securing an API is as important as building it. DRF provides several out‑of‑the‑box authentication schemes and a flexible permission system.

Common Authentication Methods

  • SessionAuthentication: Uses Django’s session framework; great for web‑based clients.
  • TokenAuthentication: Issues a simple token per user; ideal for mobile apps.
  • JWTAuthentication: JSON Web Tokens provide stateless, scalable auth (requires djangorestframework-simplejwt).

Setting Up Token Authentication

# Install the token package
pip install djangorestframework-authtoken

# Add to INSTALLED_APPS
INSTALLED_APPS += ['rest_framework.authtoken']

# Migrate
python manage.py migrate

# Update REST_FRAMEWORK settings (myproject/settings.py)
REST_FRAMEWORK = {
    'DEFAULT_AUTHENTICATION_CLASSES': [
        'rest_framework.authentication.TokenAuthentication',
    ],
    'DEFAULT_PERMISSION_CLASSES': [
        'rest_framework.permissions.IsAuthenticated',
    ],
}

Create a token for a user via the admin or the command line:

python manage.py drf_create_token your_username

Permission Classes You’ll Use Frequently

  • AllowAny – Open to all (useful for public read‑only endpoints).
  • IsAuthenticated – Requires a valid user.
  • IsAdminUser – Restricts access to staff/superusers.
  • IsOwnerOrReadOnly – Custom class that lets owners edit, others only read.

Testing Your API

Automated testing ensures your API behaves as expected. DRF extends Django’s test client with JSON support.

from rest_framework.test import APITestCase
from django.urls import reverse
from .models import Post
from django.contrib.auth.models import User

class PostAPITest(APITestCase):
    def setUp(self):
        self.user = User.objects.create_user(username='tester', password='pass')
        self.client.login(username='tester', password='pass')
        self.post = Post.objects.create(title='First', content='Hello World')

    def test_list_posts(self):
        url = reverse('post-list')  # auto‑generated by router
        response = self.client.get(url, format='json')
        self.assertEqual(response.status_code, 200)
        self.assertEqual(len(response.data), 1)

    def test_create_post(self):
        url = reverse('post-list')
        data = {'title': 'New Post', 'content': 'Content here'}
        response = self.client.post(url, data, format='json')
        self.assertEqual(response.status_code, 201)
        self.assertEqual(Post.objects.count(), 2)

Common Pitfalls and Best Practices

  • Never expose raw model fields without validation—use serializers to enforce constraints.
  • Keep your views.py thin; business logic belongs in services or model methods.
  • Leverage select_related and prefetch_related in querysets to avoid N+1 query problems.
  • Document your API with

Comments

Leave a Reply

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