Why Django REST Framework?
When I started building APIs with Python, I tried Flask first. It's lightweight and flexible, but as the project grew, I found myself reinventing things that DRF already solves well — authentication, serialization, permissions, pagination.
DRF gives you a solid foundation without locking you into magic. Let's build something real.
Project Setup
Start with a clean virtual environment:
# Create and activate virtualenv
python -m venv venv
source venv/bin/activate # Windows: venv\Scripts\activate
# Install dependencies
pip install django djangorestframework djangorestframework-simplejwt
Then create your project:
django-admin startproject myapi .
python manage.py startapp blog
Settings Configuration
Add DRF to your installed apps and configure the default authentication:
# settings.py
INSTALLED_APPS = [
...
'rest_framework',
'blog',
]
REST_FRAMEWORK = {
'DEFAULT_AUTHENTICATION_CLASSES': [
'rest_framework_simplejwt.authentication.JWTAuthentication',
],
'DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.PageNumberPagination',
'PAGE_SIZE': 10,
}
Creating the Model
# blog/models.py
from django.db import models
from django.contrib.auth.models import User
class Post(models.Model):
title = models.CharField(max_length=200)
content = models.TextField()
author = models.ForeignKey(User, on_delete=models.CASCADE)
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)
def __str__(self):
return self.title
Serializer
# blog/serializers.py
from rest_framework import serializers
from .models import Post
class PostSerializer(serializers.ModelSerializer):
author_name = serializers.CharField(source='author.username', read_only=True)
class Meta:
model = Post
fields = ['id', 'title', 'content', 'author_name', 'created_at']
ViewSet
# blog/views.py
from rest_framework import viewsets, permissions
from .models import Post
from .serializers import PostSerializer
class PostViewSet(viewsets.ModelViewSet):
queryset = Post.objects.all().order_by('-created_at')
serializer_class = PostSerializer
permission_classes = [permissions.IsAuthenticatedOrReadOnly]
def perform_create(self, serializer):
serializer.save(author=self.request.user)
That's the Core!
With this setup you get full CRUD endpoints automatically. Wire up your URLs and run migrations, and you have a working API with JWT auth and pagination out of the box.
In production, always set DEBUG = False and configure ALLOWED_HOSTS properly. Never expose your SECRET_KEY.