Install Required Dependencies
$ pip install djangorestframework
$ pip install markdown # Markdown support for the browsable API
$ pip install django-filter # Built-in filtering support
Ennable Django REST Framework in Your Project
Add the framework to your INSTALLED_APPS in your project's settings.py:
INSTALLED_APPS = [
...
'rest_framework',
]
Basic Manual Implementation
Create Project and App
$ django-admin startproject drf_demo
$ python manage.py startapp library
Define a Data Model
Add the Book model to library/models.py:
from django.db import models
class Book(models.Model):
title = models.CharField(max_length=100, verbose_name='Book Title')
price = models.IntegerField(verbose_name="Price")
publication_date = models.DateField(verbose_name="Publication Date")
Create Serializer and View Classes
Add the following code to library/views.py:
from rest_framework import serializers
from rest_framework.views import APIView
from rest_framework.response import Response
from .models import Book
# Serializer handles data validation and conversion
class BookSerializer(serializers.Serializer):
title = serializers.CharField(max_length=100)
price = serializers.IntegerField()
# Map custom field name to the underlying model field
date = serializers.DateField(source='publication_date')
def create(self, validated_data):
return Book.objects.create(**validated_data)
def update(self, instance, validated_data):
for attr, value in validated_data.items():
setattr(instance, attr, value)
instance.save()
return instance
# View for collection-level operations
class BookListHandler(APIView):
def get(self, request):
book_queryset = Book.objects.all()
serializer = BookSerializer(instance=book_queryset, many=True)
return Response(serializer.data)
def post(self, request):
serializer = BookSerializer(data=request.data)
if serializer.is_valid():
serializer.save()
return Response(serializer.data, status=201)
return Response(serializer.errors, status=400)
# View for single-item operations
class BookDetailHandler(APIView):
def get(self, request, pk):
book = Book.objects.get(pk=pk)
serializer = BookSerializer(instance=book)
return Response(serializer.data)
def put(self, request, pk):
book = Book.objects.get(pk=pk)
serializer = BookSerializer(instance=book, data=request.data)
if serializer.is_valid():
serializer.save()
return Response(serializer.data)
return Response(serializer.errors, status=400)
def delete(self, request, pk):
Book.objects.filter(pk=pk).delete()
return Response(status=204)
Configure App Routes
Create/Update library/urls.py:
from django.urls import path, re_path
from . import views
urlpatterns = [
path('', views.BookListHandler.as_view()),
re_path(r'(?P<pk>\d+)', views.BookDetailHandler.as_view()),
]
Add App Routes to Root Project URL Configuration
Update drf_demo/urls.py:
from django.urls import path, include
urlpatterns = [
...
path('books/', include('library.urls'))
]
Register You're App
Add the new app to INSTALLED_APPS in drf_demo/settings.py:
INSTALLED_APPS = [
...
'rest_framework',
'library',
]
Test Endpoints
You can test your API with the following curl commands:
# Get list of all books
curl -X GET http://your-server/books/
# Get details of a single book
curl -X GET http://your-server/books/1
# Create a new book
curl -X POST http://your-server/books/
# Update an existing book
curl -X PUT http://your-server/books/1
# Delete a book
curl -X DELETE http://your-server/books/1
Compact Implementation with ViewSets
Django REST Framework provides high-level abstractions to reduce boilerplate code. Using the same Book model from above, we can rewrite the entire API in just a few lines of code.
Update Views
Replace the content of library/views.py with:
from rest_framework.viewsets import ModelViewSet
from rest_framework import serializers
from .models import Book
class BookSerializer(serializers.ModelSerializer):
# Keep the same custom field mapping
date = serializers.DateField(source='publication_date')
class Meta:
model = Book
exclude = ['publication_date']
class BookViewSet(ModelViewSet):
queryset = Book.objects.all()
serializer_class = BookSerializer
Update Routes with DRF Router
Update urls.py to use DRF's automatic route generation:
from rest_framework import routers
from .views import BookViewSet
router = routers.DefaultRouter()
router.register('books', BookViewSet)
urlpatterns = router.urls
This automatic router generates the exact same set of endpoints we created manually in the basic example, so testing works the same way as before.