python 44 lines · 1 tab

Django custom decorators for view logic

Priya Sharma Jan 2026
1 tab
from functools import wraps
from django.http import JsonResponse
from django.core.cache import cache


def ajax_required(view_func):
    """Decorator to ensure request is AJAX."""
    @wraps(view_func)
    def wrapper(request, *args, **kwargs):
        if not request.headers.get('X-Requested-With') == 'XMLHttpRequest':
            return JsonResponse({'error': 'AJAX required'}, status=400)
        return view_func(request, *args, **kwargs)
    return wrapper


def rate_limit(key_prefix, limit=10, period=60):
    """Simple rate limiting decorator."""
    def decorator(view_func):
        @wraps(view_func)
        def wrapper(request, *args, **kwargs):
            # Create cache key from IP or user
            if request.user.is_authenticated:
                cache_key = f'{key_prefix}:{request.user.id}'
            else:
                cache_key = f'{key_prefix}:{request.META.get("REMOTE_ADDR")}'

            # Check rate limit
            count = cache.get(cache_key, 0)
            if count >= limit:
                return JsonResponse({'error': 'Rate limit exceeded'}, status=429)

            # Increment counter
            cache.set(cache_key, count + 1, period)
            return view_func(request, *args, **kwargs)

        return wrapper
    return decorator


# Usage
@ajax_required
@rate_limit('api_endpoint', limit=100, period=3600)
def my_api_view(request):
    return JsonResponse({'status': 'ok'})
1 file · python Explain with highlit

Custom decorators encapsulate reusable view logic. I use functools.wraps to preserve function metadata. For class-based views, I use method_decorator. Common patterns include permission checks, rate limiting, or request validation. Decorators can modify request/response or short-circuit with early returns. I stack multiple decorators carefully—order matters. For complex logic, middleware might be better than decorators. This keeps views clean and promotes code reuse across endpoints.


Related snips

python
import os
import stat

for root, _dirs, files in os.walk('/etc'):
    for name in files:
        path = os.path.join(root, name)

Python security audit script for exposed risky filesystem state

python auditing host-security
by Kai Nakamura 1 tab
python
class Product(models.Model):
    name = models.CharField(max_length=200)
    slug = models.SlugField(blank=True)
    price = models.DecimalField(max_digits=10, decimal_places=2)
    cost = models.DecimalField(max_digits=10, decimal_places=2)
    margin = models.DecimalField(max_digits=5, decimal_places=2, blank=True)

Django model signals vs overriding save

django python models
by Priya Sharma 2 tabs
python
from django.urls import path
from . import views

app_name = 'blog'

urlpatterns = [

Django URL namespacing and reverse lookups

django python urls
by Priya Sharma 3 tabs
python
import graphene
from graphene_django import DjangoObjectType
from blog.models import Post, Comment


class PostType(DjangoObjectType):

Django GraphQL with Graphene

django python graphql
by Priya Sharma 2 tabs
python
from django.db.models import Count, Avg, Sum, Q, F
from django.views.generic import TemplateView
from products.models import Product, Order, OrderItem


class DashboardView(TemplateView):

Django aggregation with annotate for statistics

django python database
by Priya Sharma 1 tab
python
from rest_framework import permissions


class IsOwner(permissions.BasePermission):
    """Allow only object owner to access."""

Django REST Framework permissions and authorization

django python rest
by Priya Sharma 2 tabs

Share this code

Here's the card — post it anywhere.

Django custom decorators for view logic — share card
Link copied