What is Throttling?
Throttling is a technique used to control the number of requests a client can make to an API over a specific time period. This helps:
Prevent API abuse
Ensure fair usage
Reduce server load
In this tutorial, we’ll build a simple Django REST API with throttling, allowing a maximum of 2 submissions per IP in 24 hours.
🏗️ Step 1: Set Up the Django Project
Create a new Django project:
django-admin startproject throttling
Create a new app inside the project:
cd throttling
python manage.py startapp core
Install Django REST Framework:
pip install djangorestframework
Add the apps to INSTALLED_APPS
in throttling/settings.py:
INSTALLED_APPS = [
...
'rest_framework',
'core',
]
⚙️ Step 2: Optional Global Throttle Settings
You can set default throttling behavior in settings.py
REST_FRAMEWORK = {
'DEFAULT_THROTTLE_CLASSES': [
'rest_framework.throttling.AnonRateThrottle',
],
'DEFAULT_THROTTLE_RATES': {
'anon': '2/min', # 2 request per minute for anonymous users
}
}
In this guide, we’ll use custom per-view throttling instead.
📦 Step 3: Create the Book Model
In core/models.py:
from django.db import models
class Book(models.Model):
name = models.CharField(max_length=100)
genre = models.CharField(max_length=50)
created_at = models.DateField(auto_now_add=True)
ip_address = models.GenericIPAddressField(null=True, blank=True)
class Meta:
ordering = ['-created_at']
verbose_name = 'Book'
def __str__(self):
return f"{self.name} - {self.ip_address}"
Apply the migrations:
python manage.py makemigrations core
python manage.py migrate
🔄 Step 4: Create a Serializer
In core/serializer.py
:
from rest_framework import serializers
from .models import Book
class BookSerializer(serializers.ModelSerializer):
class Meta:
model = Book
fields = ['id', 'name', 'genre', 'ip_address', 'created_at']
📡 Step 5: Create the View with Throttling Logic
In core/views.py:
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework import status
from datetime import datetime, timedelta
from .models import Book
from .serializers import BookSerializer
class BookAPIView(APIView):
def get_client_ip(self, request):
x_forwarded_for = request.META.get('HTTP_X_FORWARDED_FOR')
if x_forwarded_for:
ip = x_forwarded_for.split(',')[0]
else:
ip = request.META.get('REMOTE_ADDR')
return ip
def get(self, request):
books = Book.objects.all()
serializer = BookSerializer(books, many=True)
return Response({
"message": "Successfully retrieved books",
"status": "success",
"data": serializer.data
}, status=status.HTTP_200_OK)
def post(self, request):
ip = self.get_client_ip(request)
time_limit = datetime.now() - timedelta(hours=24)
submissions_count = Book.objects.filter(
ip_address=ip, created_at__gte=time_limit).count()
if submissions_count >= 2:
return Response({
"message": "Submission limit reached. Max 2 per 24 hours from the same IP.",
"status": "error"
}, status=status.HTTP_429_TOO_MANY_REQUESTS)
serializer = BookSerializer(data=request.data)
if serializer.is_valid():
serializer.save(ip_address=ip)
return Response({
"message": "Successfully posted book",
"status": "success",
"data": serializer.data
}, status=status.HTTP_201_CREATED)
return Response({
"message": "Failed to create book",
"status": "error",
"errors": serializer.errors
}, status=status.HTTP_400_BAD_REQUEST)
🧭 Step 6: Setup URLs
In core/urls.py
:
from django.urls import path
from .views import BookAPIView
urlpatterns = [
path('', BookAPIView.as_view(), name='book'),
]
In throttling/urls.py:
from django.contrib import admin
from django.urls import path, include
urlpatterns = [
path('admin/', admin.site.urls),
path('api/core', include('core.urls')),
]
✅ Step 7: Test the API
Start your development server
python manage.py runserver
Send a GET request to /api/core
→ returns a list of books to see
But when you try to request continually you see as below throttling is working by controlling the rate at which clients can make requests to API.
Top comments (0)