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.