Я использую Flask и имею два декоратора, которые я пытаюсь использовать на определенных маршрутах, чтобы быть более Pythonic, предотвращать повторное использование кода и улучшать читаемость.
Первый из них просто проверяет, вошел ли пользователь в систему, иначе перенаправляет пользователя на страницу входа. Это нормально работает.
После этого я проверяю класс пользователя (администратор, менеджер, стандартный пользователь и т. д.), Однако он не работает, и я не уверен, чего не хватает.
Из 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, единственное, что я могу предположить, это, возможно, сеанс не переносится, хотя он включен из фляга в модуль и маршруты, но опять же, я не уверен как это можно исправить.
Что я пытаюсь сделать с этим: иметь маршруты, которые используют оба декоратора и не требуют проверки 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
? Я пробовал это несколькими разными способами, и все равно возникали ошибки.
Очень признателен!
Вам нужно вернуть внутреннюю функцию 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 (most recent call last): File "", line 1, in TypeError: 'NoneType' object is not callable
@ Карл Рад помочь! Я добавил дополнительное объяснение. Пожалуйста, посмотрите мою недавнюю правку.
Спасибо!! Я знал, что мне не хватало чего-то очевидного !! Я не могу проголосовать за ваше решение, но когда смогу, сделаю это. Еще раз спасибо!