简体   繁体   中英

Function decorator not being invoked

This has been driving me crazy because it should be so simple, but there must be some Python quirk I'm missing. I have a decorator that I'm trying to apply to a Flask route, but for some reason none of the decorators in my views.py seem to be getting loaded.

decorators.py

def admin_required(func):
    """Require App Engine admin credentials."""
    @wraps(func)
    def decorated_view(*args, **kwargs):
        if users.get_current_user():
            if not users.is_current_user_admin():
                abort(401)  # Unauthorized
            return func(*args, **kwargs)
        return redirect(users.create_login_url(request.url))
    return decorated_view

views.py

@admin_required
@blueprint.route('/')
def index():
    return render_template('index.html')

The admin_required decorator function is not being called (index.html is loaded without a redirect), and I cannot figure out why.

Short answer: change the order of the decorators; blueprint.route only "sees" your undecorated function.

Decorators are applied inside-out, in loose analogy to function calls. Thus your function definition is equivalent to:

def index():
    return render_template('index.html')
index = blueprint.route('/')(index)
index = admin_required(index)

Note how blueprint.route is passed the index function before it gets wrapped by admin_required . Of course, admin_required does eventually get applied to the index name in the module, so if you were to call index directly, it would go through both decorators. But you're not calling it directly, you're telling flask's request processor to call it.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM