This rule enforces that the @receiver decorator in Django and the @route decorator in Flask are placed on top of all
other decorators.
The order in which decorators are applied can have a significant impact on their behavior. When decorators are applied in Python, they are processed from bottom to top. The outermost decorator (the one written first) is applied last and receives the result of all inner decorators.
In Django, the @receiver decorator is used to register signal handlers. It must be the outermost decorator (written at the top) so
that all other decorators are applied to the function before it gets registered as a signal handler. If @receiver is not outermost, it
registers the original function, and the decorators written above it will not affect the signal handler, resulting in unexpected behavior or
errors.
In Flask, the @app.route() or @blueprint.route() decorator must be the outermost decorator for view functions. If other
decorators are placed outside the route decorator, the route may not be registered correctly, leading to 404 errors or routes that don’t respond to
requests as expected.
Move the @receiver decorator to the top of the list of decorators used to decorate the function.
from django.dispatch import receiver
from django.views.decorators.csrf import csrf_exempt
@csrf_exempt
@receiver(some_signal) # Noncompliant: @receiver should be the outermost decorator
def my_handler(sender, **kwargs):
...
from django.dispatch import receiver
from django.views.decorators.csrf import csrf_exempt
@receiver(some_signal)
@csrf_exempt
def my_handler(sender, **kwargs):
...
Move the @app.route() or @blueprint.route() decorator to be the outermost (first) decorator.
@login_required
@app.route('/secret_page') # Noncompliant: @route should be the outermost decorator
def secret_page():
return "Secret content"
@app.route('/secret_page')
@login_required
def secret_page():
return "Secret content"