Building RESTful APIs with Django and Python

Python and Django have emerged as a dynamic duo in the world of web development, empowering developers to create robust and scalable applications. Python, known for its simplicity and readability, provides an elegant programming language for building a wide range of applications. Meanwhile, Django, a highlevel web framework written in Python, offers a comprehensive toolkit for rapid development and clean design.

In this tutorial, we will explore the process of building RESTful APIs using Django and Python. We'll cover everything from setting up a new Django project to designing and implementing API endpoints with proper serialization and routing.

Setting Up Django Project

To begin, we need to set up a new Django project and install Django REST Framework ?

$ pip install django djangorestframework
$ django-admin startproject myproject
$ cd myproject
$ python manage.py startapp api

Add the following to your settings.py file ?

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

Creating the Model

First, let's create a simple Post model in api/models.py ?

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

Run migrations to create the database table ?

$ python manage.py makemigrations
$ python manage.py migrate

Creating Serializers

Serializers convert Django model instances to JSON format and validate incoming data. Create api/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']
        read_only_fields = ['created_at']

Implementing API Views

Create API views in api/views.py to handle CRUD operations ?

from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework import status
from .models import Post
from .serializers import PostSerializer

class PostListView(APIView):
    def get(self, request):
        posts = Post.objects.all()
        serializer = PostSerializer(posts, many=True)
        return Response(serializer.data)
    
    def post(self, request):
        serializer = PostSerializer(data=request.data)
        if serializer.is_valid():
            serializer.save()
            return Response(serializer.data, status=status.HTTP_201_CREATED)
        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

class PostDetailView(APIView):
    def get_object(self, pk):
        try:
            return Post.objects.get(pk=pk)
        except Post.DoesNotExist:
            return None
    
    def get(self, request, pk):
        post = self.get_object(pk)
        if not post:
            return Response({'error': 'Post not found'}, 
                          status=status.HTTP_404_NOT_FOUND)
        serializer = PostSerializer(post)
        return Response(serializer.data)
    
    def put(self, request, pk):
        post = self.get_object(pk)
        if not post:
            return Response({'error': 'Post not found'}, 
                          status=status.HTTP_404_NOT_FOUND)
        serializer = PostSerializer(post, data=request.data)
        if serializer.is_valid():
            serializer.save()
            return Response(serializer.data)
        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
    
    def delete(self, request, pk):
        post = self.get_object(pk)
        if not post:
            return Response({'error': 'Post not found'}, 
                          status=status.HTTP_404_NOT_FOUND)
        post.delete()
        return Response(status=status.HTTP_204_NO_CONTENT)

URL Configuration

Create api/urls.py to define URL patterns ?

from django.urls import path
from .views import PostListView, PostDetailView

urlpatterns = [
    path('posts/', PostListView.as_view(), name='post-list'),
    path('posts/<int:pk>/', PostDetailView.as_view(), name='post-detail'),
]

Include the API URLs 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('api.urls')),
]

Testing the API

Start the development server and test your API endpoints ?

$ python manage.py runserver

You can now test these endpoints using tools like curl or Postman:

  • GET /api/posts/ List all posts
  • POST /api/posts/ Create a new post
  • GET /api/posts/1/ Retrieve a specific post
  • PUT /api/posts/1/ Update a specific post
  • DELETE /api/posts/1/ Delete a specific post

Using Generic Views (Alternative Approach)

Django REST Framework provides generic views that reduce code duplication. You can replace the above views with ?

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

class PostListCreateView(generics.ListCreateAPIView):
    queryset = Post.objects.all()
    serializer_class = PostSerializer

class PostDetailView(generics.RetrieveUpdateDestroyAPIView):
    queryset = Post.objects.all()
    serializer_class = PostSerializer

Conclusion

Building RESTful APIs with Django and Django REST Framework provides a robust foundation for web applications. The combination of models, serializers, and views creates a clean separation of concerns while maintaining flexibility for complex requirements.

---
Updated on: 2026-03-27T08:55:14+05:30

690 Views

Kickstart Your Career

Get certified by completing the course

Get Started
Advertisements