Subjects

All subjects Django Java Python React Spring Boot JavaScript PHP
Sign Up Free
Question 6 of 10 · Django Signals & Decorators
Interview question

How do you chain multiple decorators? What is the order of execution? Multiple decorators को कैसे chain करते हैं? Execution order क्या है?

Answer

Multiple decorators are applied bottom-up during definition but executed top-down during function call. Understanding the order is critical to avoid bugs.

// Simple Decorator Chain
def decorator1(func):
    print("D1 decorated")
    def wrapper(*args, **kwargs):
        print("D1 before")
        result = func(*args, **kwargs)
        print("D1 after")
        return result
    return wrapper

def decorator2(func):
    print("D2 decorated")
    def wrapper(*args, **kwargs):
        print("D2 before")
        result = func(*args, **kwargs)
        print("D2 after")
        return result
    return wrapper

// Order of execution
@decorator1
@decorator2
def my_function():
    print("Function executed")

my_function()

// EXECUTION OUTPUT:
// D2 decorated (bottom decorator applied first)
// D1 decorated (top decorator applied second)
// D1 before (top decorator executes first)
// D2 before
// Function executed
// D2 after
// D1 after (top decorator executes last)

// Django Example - Multiple Permissions
from django.contrib.auth.decorators import login_required, permission_required

@login_required
@permission_required("myapp.can_edit_books")
def edit_book(request, book_id):
    return JsonResponse({"status": "editing"})

// EXECUTION ORDER:
// 1. Check if user is authenticated (login_required)
// 2. Check if user has permission (permission_required)
// 3. Execute edit_book view

// Practical Django Example
def timing_decorator(func):
    def wrapper(*args, **kwargs):
        import time
        start = time.time()
        result = func(*args, **kwargs)
        print(f"Execution time: {time.time() - start}s")
        return result
    return wrapper

def auth_decorator(func):
    def wrapper(request, *args, **kwargs):
        if not request.user.is_authenticated:
            return redirect("login")
        return func(request, *args, **kwargs)
    return wrapper

@timing_decorator
@auth_decorator
def dashboard(request):
    return render(request, "dashboard.html")

// EXECUTION ORDER on call:
// 1. auth_decorator checks authentication
// 2. dashboard executes
// 3. timing_decorator measures time

// Complex Chain with Caching
from functools import wraps

def cache_result(timeout=300):
    def decorator(func):
        @wraps(func)
        def wrapper(*args, **kwargs):
            cache_key = f"{func.__name__}_{str(args)}_{str(kwargs)}"
            result = cache.get(cache_key)
            if result is None:
                result = func(*args, **kwargs)
                cache.set(cache_key, result, timeout)
            return result
        return wrapper
    return decorator

def log_execution(func):
    @wraps(func)
    def wrapper(*args, **kwargs):
        logger.info(f"Calling {func.__name__}")
        return func(*args, **kwargs)
    return wrapper

@log_execution
@cache_result(timeout=600)
def expensive_operation(n):
    time.sleep(2)
    return n * 2

// EXECUTION:
// 1. log_execution wrapper called
// 2. cache_result wrapper checks cache
// 3. expensive_operation executes (if not cached)
// 4. result cached and returned

Multiple decorators bottom-up apply होते हैं लेकिन top-down execute होते हैं।

@decorator1
@decorator2
def my_func():
    print("Function")

// Definition order:
// D2 applied, then D1

// Execution order:
// D1 runs first, then D2, then function, then D2, then D1

// Output:
// D1 before
// D2 before
// Function
// D2 after
// D1 after

Was this answer clear?