How to Use Django REST Framework to Build an API

Building APIs is an essential skill for modern web developers, and Django REST Framework (DRF) makes the process both powerful and elegant. Whether you’re connecting a mobile app, powering a frontend built with React or Vue, or exposing services for third-party integrations, DRF gives you the tools to create reliable, secure, and scalable APIs. In this post, we’ll walk through the fundamentals of using Django REST Framework to build an API, with plenty of practical examples.


Why Use Django REST Framework?

Django itself is a batteries-included framework for building web applications. But when it comes to APIs, you often need specialized tools for:

  • Serializing data into JSON or XML.
  • Handling authentication and permissions.
  • Providing browsable API endpoints for easy debugging.
  • Managing querysets and filtering.

That’s where Django REST Framework comes in. It builds on Django’s ORM and request/response handling while adding flexible features specifically for APIs.


Setting Up Your Environment

Before starting, make sure you have Python and Django installed. Then install DRF:

pip install djangorestframework

Next, add rest_framework to your INSTALLED_APPS in settings.py:

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

You’re now ready to start building.


Step 1: Create a Django Project and App

Start a new project and app:

django-admin startproject myproject
cd myproject
python manage.py startapp blog

Add the app (blog) to INSTALLED_APPS in settings.py.


Step 2: Define a Model

Let’s create a simple blog post model in blog/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:

python manage.py makemigrations
python manage.py migrate

Step 3: Create a Serializer

Serializers translate Django models into JSON (or other formats). In 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']

This ModelSerializer automatically handles serialization and deserialization for us.


Step 4: Write Views

DRF provides several view classes. For CRUD operations, ModelViewSet is the simplest choice. In blog/views.py:

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

This single class gives you endpoints for listing, creating, retrieving, updating, and deleting posts.


Step 5: Configure URLs

In 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)),
]

Now your API is live! Visit http://127.0.0.1:8000/api/posts/ to test it. DRF provides a browsable interface where you can view, add, edit, and delete posts.


Step 6: Test the API

Start the server:

python manage.py runserver

Then test with curl or Postman:

  • List posts: curl http://127.0.0.1:8000/api/posts/
  • Create a new post: curl -X POST http://127.0.0.1:8000/api/posts/ \ -H "Content-Type: application/json" \ -d '{"title": "My First Post", "content": "Hello, world!"}'

Step 7: Add Authentication and Permissions

By default, DRF lets anyone access your API. Let’s secure it.

In settings.py:

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

Now, only authenticated users can access the API. You can also use token authentication:

pip install djangorestframework-simplejwt

Then configure JWT in your settings for token-based access.


Step 8: Filtering, Searching, and Pagination

DRF makes it easy to filter and paginate.

Install Django Filter:

pip install django-filter

Update settings.py:

REST_FRAMEWORK = {
    'DEFAULT_FILTER_BACKENDS': [
        'django_filters.rest_framework.DjangoFilterBackend',
        'rest_framework.filters.SearchFilter',
        'rest_framework.filters.OrderingFilter',
    ],
    'DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.PageNumberPagination',
    'PAGE_SIZE': 10,
}

Update your view:

class PostViewSet(viewsets.ModelViewSet):
    queryset = Post.objects.all().order_by('-created_at')
    serializer_class = PostSerializer
    filterset_fields = ['title']
    search_fields = ['title', 'content']
    ordering_fields = ['created_at']

Now you can:

  • Filter: /api/posts/?title=My%20First%20Post
  • Search: /api/posts/?search=hello
  • Order: /api/posts/?ordering=created_at

Step 9: Versioning Your API

As APIs evolve, versioning helps avoid breaking changes. Add versioning in settings.py:

REST_FRAMEWORK = {
    'DEFAULT_VERSIONING_CLASS': 'rest_framework.versioning.NamespaceVersioning',
}

In urls.py:

urlpatterns = [
    path('api/v1/', include((router.urls, 'blog'), namespace='v1')),
]

Now your endpoints live under /api/v1/posts/, leaving room for future versions.


Step 10: Document Your API

DRF supports automatic documentation using tools like drf-yasg or Swagger/OpenAPI.

pip install drf-yasg

In urls.py:

from rest_framework import permissions
from drf_yasg.views import get_schema_view
from drf_yasg import openapi

schema_view = get_schema_view(
   openapi.Info(
      title="Blog API",
      default_version='v1',
      description="API documentation for the blog",
   ),
   public=True,
   permission_classes=(permissions.AllowAny,),
)

urlpatterns += [
    path('swagger/', schema_view.with_ui('swagger', cache_timeout=0), name='schema-swagger-ui'),
]

Now you have interactive API docs at /swagger/.


Wrapping Up

We’ve just built a complete API with Django REST Framework:

  • Defined models and serializers.
  • Created viewsets and routes.
  • Added authentication, filtering, pagination, and versioning.
  • Documented the API with Swagger.

This foundation can power blogs, ecommerce sites, SaaS platforms, and more. Once you’re comfortable, you can explore advanced topics like custom permissions, throttling, caching, and asynchronous tasks with Django Channels.

Django REST Framework is powerful but approachable, making it one of the best choices for building APIs in Python. With a few lines of code, you can create robust, secure endpoints that scale as your project grows.


Next steps: Try extending the blog API with comments, user profiles, or JWT authentication. Or, connect it to a React frontend to create a fully decoupled app. The possibilities are wide open.