Пользовательский декоратор Flask не работает должным образом

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

Очень признателен!

Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
0
0
486
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Вам нужно вернуть внутреннюю функцию 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

Спасибо!! Я знал, что мне не хватало чего-то очевидного !! Я не могу проголосовать за ваше решение, но когда смогу, сделаю это. Еще раз спасибо!

Carl 01.05.2018 17:45

@ Карл Рад помочь! Я добавил дополнительное объяснение. Пожалуйста, посмотрите мою недавнюю правку.

Ajax1234 01.05.2018 17:48

Другие вопросы по теме