Flask 自定义装饰器未按预期运行

Flask custom decorator not functioning as expected

我正在使用 Flask 并有两个装饰器,我试图在某些路线上使用它们以使其更加 Pythonic,防止代码重用并提高可读性。

第一个只是检查用户是否登录,否则将用户重定向到登录页面。这很好用。

在此之后,我检查了用户 'class'(管理员、经理、标准用户等),但是这个没有用,我不确定缺少什么。

来自routes.py:

@app.route('/user/user-account.html', methods=['GET', 'POST'])
@login_required
def cna_account():
    if valid_user() == True:
        result = get_user_account()
        return render_template('user/user-account.html', result=result)
    else:
        return redirect(url_for('index'))

@login_reqiured 工作正常,这里是代码:

@wraps(f)
def wrap(*args, **kwargs):
    if 'logged_in' in session:
        return f(*args, **kwargs)
    else:
        return redirect(url_for('index'))
return wrap

我为其他不起作用的装饰器所做的尝试:

def valid_user(f): ''' 确保只有基本用户可以查看基本用户页面 '''

@wraps(f)
def wrap(*args, **kwargs):
    if 'access' in session and session['access'] == 'c':
        return f(*args, **kwargs)
    else:
        return redirect(url_for('index'))

这些存储在 routes.py 中导入的单独模块中,我唯一能猜到的是即使会话包含在 flask[ 中,它也可能没有被执行=42=] 在模块和路由中,但我再次不确定如何补救。

我想用它做的是:拥有同时使用装饰器且不需要 if valid_user() == True 检查的路由。相反,它应该起作用并且看起来像:

@app.route('/user/user-account.html', methods=['GET', 'POST'])
@login_required
@valid_user
def cna_account():
    result = get_user_account()
    return render_template('user/user-account.html', result=result)

关于我在这里遗漏的任何帮助?我是否需要将会话变量作为参数传递给 @valid_user?我尝试了几种不同的方法,但仍然抛出错误。

非常感谢!

您需要 return valid_user 中的内部函数 wrap:

def valid_user(f): 
  @wraps(f)
  def wrap(*args, **kwargs):
    if 'access' in session and session['access'] == 'c':
      return f(*args, **kwargs)
    return redirect(url_for('index'))
  return wrap

虽然不 return 来自外部装饰器函数的任何东西是完全有效的,但请记住,包装函数在 运行 时间传递给包装器,因此, returned 值将是 None:

def foo(f):
   print("inside decorator with '{}'".format(f.__name__))
   def inner():
      return 10

@foo
def bar():
  return 'in bar'

"inside decorator with 'bar'"
>>>bar()

Traceback (most recent call last): File "", line 1, in TypeError: 'NoneType' object is not callable