Django REST Framework (DRF) is a powerful and flexible toolkit for building Web APIs in Django. If you've used Django for building web apps, DRF will feel natural but adds great tools for API serialization, request parsing, authentication, and more.
Why Use DRF?
-
Provides serializers to transform complex data into JSON and vice versa.
-
Helps create standardized RESTful APIs quickly.
-
Built-in support for authentication, permissions, pagination, filtering, etc.
-
Easily integrates with your Django models and views.
Step-by-Step Setup & Basic API
Step 1: Install DRF
pip install djangorestframework
Add it to INSTALLED_APPS
in settings.py
:
INSTALLED_APPS = [
...
'rest_framework',
]
Step 2: Create a Django Project & App
django-admin startproject myapi
cd myapi
python manage.py startapp blog
Add blog
to INSTALLED_APPS
.
Step 3: Create a Model
In blog/models.py
:
from django.db import models
class Post(models.Model):
title = models.CharField(max_length=100)
content = models.TextField()
created_at = models.DateTimeField(auto_now_add=True)
def __str__(self):
return self.title
Apply migrations:
python manage.py makemigrations
python manage.py migrate
Step 4: Create a Serializer
In blog/serializers.py
:
from rest_framework import serializers
from .models import Post
class PostSerializer(serializers.ModelSerializer):
class Meta:
model = Post
fields = '__all__'
Step 5: Create a ViewSet
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()
serializer_class = PostSerializer
Step 6: Set Up URLs
In blog/urls.py
(create it if it doesn't exist):
from django.urls import path, include
from rest_framework.routers import DefaultRouter
from .views import PostViewSet
router = DefaultRouter()
router.register(r'posts', PostViewSet)
urlpatterns = [
path('', include(router.urls)),
]
In myapi/urls.py
:
from django.contrib import admin
from django.urls import path, include
urlpatterns = [
path('admin/', admin.site.urls),
path('api/', include('blog.urls')),
]
✅ Running the API
python manage.py runserver
Visit:
-
http://127.0.0.1:8000/api/posts/
for list and create -
http://127.0.0.1:8000/api/posts/1/
for retrieve, update, delete
Tips
-
Use
ModelSerializer
to reduce boilerplate code. -
Use ViewSets and Routers for quick CRUD APIs.
-
Enable Browsable API for easier testing via the browser.
-
Explore Generic Views for custom logic when needed.
⚠️ Common Pitfalls
Pitfall | Solution |
---|---|
Forgetting to register the app or DRF in INSTALLED_APPS |
Always double-check settings.py |
Not importing include() in urls.py |
from django.urls import include |
Missing migrations after model changes | Run makemigrations and migrate |
Using APIView instead of ViewSet and expecting automatic routing |
Use ModelViewSet with routers |
Serialization errors | Check for read-only/write-only fields or incorrect data formats |
Complete Example
Project structure:
myapi/
├── blog/
│ ├── models.py
│ ├── views.py
│ ├── serializers.py
│ ├── urls.py
├── myapi/
│ ├── settings.py
│ ├── urls.py
✅ models.py
from django.db import models
class Post(models.Model):
title = models.CharField(max_length=100)
content = models.TextField()
created_at = models.DateTimeField(auto_now_add=True)
def __str__(self):
return self.title
✅ serializers.py
from rest_framework import serializers
from .models import Post
class PostSerializer(serializers.ModelSerializer):
class Meta:
model = Post
fields = '__all__'
✅ views.py
from rest_framework import viewsets
from .models import Post
from .serializers import PostSerializer
class PostViewSet(viewsets.ModelViewSet):
queryset = Post.objects.all()
serializer_class = PostSerializer
✅ blog/urls.py
from django.urls import path, include
from rest_framework.routers import DefaultRouter
from .views import PostViewSet
router = DefaultRouter()
router.register(r'posts', PostViewSet)
urlpatterns = [
path('', include(router.urls)),
]
✅ myapi/urls.py
from django.contrib import admin
from django.urls import path, include
urlpatterns = [
path('admin/', admin.site.urls),
path('api/', include('blog.urls')),
]
What’s Next?
After this, consider learning:
-
Authentication and Permissions
-
Filtering & Pagination
-
API testing with Postman or Django’s
APIClient
-
Deployment with Docker