Building Your First Django REST API

Building REST APIs with Django has become one of the most popular ways to create backend services for modern web and mobile applications. In this comprehensive guide, we’ll walk through creating your first Django REST API from scratch.

What is Django REST Framework?

Django REST Framework (DRF) is a powerful toolkit for building Web APIs in Django. It provides a flexible, feature-rich framework that makes it easy to build REST APIs with minimal code while maintaining best practices.

Setting Up Your Environment

First, let’s create a new Django project and install the necessary dependencies:

# Create virtual environment
python -m venv venv
source venv/bin/activate  # On Windows: venv\Scripts\activate

# Install Django and DRF
pip install django djangorestframework

# Create new project
django-admin startproject blog_api
cd blog_api
python manage.py startapp posts

Configuring Django Settings

Add the REST framework to your settings.py:

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'rest_framework',
    'posts',
]

REST_FRAMEWORK = {
    'DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.PageNumberPagination',
    'PAGE_SIZE': 20,
    'DEFAULT_AUTHENTICATION_CLASSES': [
        'rest_framework.authentication.SessionAuthentication',
    ],
    'DEFAULT_PERMISSION_CLASSES': [
        'rest_framework.permissions.IsAuthenticatedOrReadOnly',
    ],
}

Creating Your Model

Let’s create a simple blog post model in posts/models.py:

from django.db import models
from django.contrib.auth.models import User

class Post(models.Model):
    title = models.CharField(max_length=200)
    content = models.TextField()
    author = models.ForeignKey(User, on_delete=models.CASCADE)
    created_at = models.DateTimeField(auto_now_add=True)
    updated_at = models.DateTimeField(auto_now=True)
    published = models.BooleanField(default=False)

    class Meta:
        ordering = ['-created_at']

    def __str__(self):
        return self.title

Creating Serializers

Serializers in DRF convert model instances to JSON and vice versa. Create posts/serializers.py:

from rest_framework import serializers
from .models import Post

class PostSerializer(serializers.ModelSerializer):
    author = serializers.StringRelatedField(read_only=True)
    
    class Meta:
        model = Post
        fields = ['id', 'title', 'content', 'author', 'created_at', 'updated_at', 'published']
        read_only_fields = ['id', 'created_at', 'updated_at']

    def create(self, validated_data):
        # Automatically set the author to the current user
        validated_data['author'] = self.context['request'].user
        return super().create(validated_data)

Building API Views

Create your API views in posts/views.py:

from rest_framework import generics, permissions
from rest_framework.decorators import api_view
from rest_framework.response import Response
from .models import Post
from .serializers import PostSerializer

class PostListCreateView(generics.ListCreateAPIView):
    queryset = Post.objects.filter(published=True)
    serializer_class = PostSerializer
    permission_classes = [permissions.IsAuthenticatedOrReadOnly]

class PostDetailView(generics.RetrieveUpdateDestroyAPIView):
    queryset = Post.objects.all()
    serializer_class = PostSerializer
    permission_classes = [permissions.IsAuthenticatedOrReadOnly]

    def get_queryset(self):
        if self.request.user.is_authenticated:
            return Post.objects.all()
        return Post.objects.filter(published=True)

URL Configuration

Set up your URLs in posts/urls.py:

from django.urls import path
from . import views

urlpatterns = [
    path('posts/', views.PostListCreateView.as_view(), name='post-list'),
    path('posts//', views.PostDetailView.as_view(), name='post-detail'),
]

And include them in your main urls.py:

from django.contrib import admin
from django.urls import path, include

urlpatterns = [
    path('admin/', admin.site.urls),
    path('api/', include('posts.urls')),
    path('api-auth/', include('rest_framework.urls')),
]

Testing Your API

Run migrations and start the server:

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

Now you can test your API endpoints:

  • GET /api/posts/ – List all published posts
  • POST /api/posts/ – Create a new post (authenticated users)
  • GET /api/posts/1/ – Get a specific post
  • PUT /api/posts/1/ – Update a post (author only)
  • DELETE /api/posts/1/ – Delete a post (author only)

Next Steps

This basic API can be extended with features like:

  • Custom authentication (JWT tokens)
  • Advanced filtering and searching
  • File uploads for images
  • API versioning
  • Rate limiting
  • Comprehensive testing

Django REST Framework provides all the tools you need to build production-ready APIs. Start with this foundation and gradually add more advanced features as your application grows.

Author

  • Mohammad Golam Dostogir, Software Engineer specializing in Python, Django, and AI solutions. Active contributor to open-source projects and tech communities, with experience delivering applications for global companies.
    GitHub

    View all posts
Index