简体   繁体   English

当我的装饰器接受参数时,Flask-Login中断

[英]Flask-Login breaks when my decorator accepts parameters

Thanks to what I learned from this question , I've been able to make a Flask-Login process with a endpoint like this: 感谢我从这个问题中学到的东西,我已经能够使用这样的端点进行Flask-Login过程:

@app.route('/top_secret')
@authorize
@login_required
def top_secret():
    return render_template("top_secret.html")

and (for now) a completely pass-through "authorize" decorator: 和(目前)一个完全通过的“授权”装饰器:

from functools import wraps

def authorize(func):
    @wraps(func)
    def newfunc(*args, **kwargs):
        return func(*args, **kwargs)
    return newfunc

The @wraps(func) call allows Flask to find the endpoint that it's looking for. @wraps(func)调用允许Flask找到它正在寻找的端点。 So far, so good. 到现在为止还挺好。

But I want to pass an group name to the "authorize" process, and things go bad when I try to make a decorator that accepts incoming parameters. 但是我想将一个组名称传递给“授权”进程,当我尝试创建一个接受传入参数的装饰器时,事情就变坏了。 This seems to be the correct syntax, unless I'm mistaken: 这似乎是正确的语法,除非我弄错了:

from functools import wraps

def authorize(group=None):
    def real_authorize(func):
        @wraps(func)
        def newfunc(*args, **kwargs):
            return func(*args, **kwargs)
        return newfunc
    return real_authorize

But once again the error appears as Flask is unable to figure out the 'top-secret' endpoint: 但是,由于Flask无法找出“绝密”端点,因此错误再次出现:

werkzeug.routing.BuildError: Could not build url for endpoint 'top_secret'.

I thought perhaps it needed @wraps(authorize) decoration right above def real_authorize(func) , but that did nothing to help. 我以为它可能需要在def real_authorize(func)上方进行@wraps(authorize)装饰,但这无济于事。

Can someone help me figure out where my @wraps are going wrong? 有人能帮我弄明白我的@wraps出错了吗?

Decorating a function is equivalent to re-binding the name to the result of calling the decorator with the function. 装饰函数等效于将名称重新绑定到使用函数调用装饰器的结果。

@authorize
def top_secret():
    ...

# is equivalent to

def top_secret():
    ...
top_secret = authorize(top_secret)

The function you've written is a decorator factory : you call it, with an optional argument, to get a decorator. 你编写的函数是一个装饰工厂 :用一个可选参数调用它来获取装饰器。

@authorize()
def top_secret():
    ...

# is equivalent to

def top_secret():
    ...
top_secret = authorize()(top_secret)

Currently, you're passing top_secret as the group argument to the factory, so you're never actually creating a route. 目前,您将top_secret作为group参数传递给工厂,因此您实际上从未创建过路由。 Since there's no route, there's no url to build either. 由于没有路由,因此也没有要构建的网址。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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