Настраиваемый декоратор Flask не работает должным образом - PullRequest
0 голосов
/ 01 мая 2018

Я использую Flask и у меня есть два декоратора, которые я пытаюсь использовать на определенных маршрутах, чтобы сделать их более Pythonic, предотвратить повторное использование кода и улучшить читаемость.

Первый из них - просто проверка того, вошел ли пользователь, иначе перенаправьте пользователя на страницу входа. Это отлично работает.

После этого я проверяю пользовательский «класс» (Admin, Manager, Standard User и т. Д.), Однако этот не работает, и я не уверен, чего не хватает.

Из rout.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'))

Они хранятся в отдельном модуле, который импортируется вways.py, единственное, что я могу догадаться, - это, возможно, сеанс не переносится, даже если он включен из flask в модуль и маршруты, но опять же я не уверен, как это можно исправить.

Что я пытаюсь сделать с этим: иметь маршруты, которые используют оба декоратора и не требуют проверки 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? Я пробовал это несколькими разными способами, но все равно получал ошибки.

Очень ценится!

1 Ответ

0 голосов
/ 01 мая 2018

Вам необходимо вернуть внутреннюю функцию wrap в valid_user:

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

Хотя вполне допустимо ничего не возвращать из внешней функции декоратора, имейте в виду, что упакованная функция передается оболочке во время выполнения, поэтому возвращаемое значение будет 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 (последний вызов был последним): Файл "", строка 1, в Ошибка типа: объект 'NoneType' не вызывается

...