Я использую декоратор login_required
и еще один декоратор, который разбивает выходные данные на страницы. Важно, какой из них будет первым?
Имеет ли значение порядок декораторов в представлении Flask?
Ответы (4)
Хотя в этом случае, вероятно, не будет никаких проблем, независимо от порядка, вы, вероятно, захотите, чтобы login_required
выполнялся первым, чтобы вы не делали запросы и не разбивали результаты на страницы, которые будут просто отброшены.
Декораторы оборачивают исходную функцию снизу вверх, поэтому при вызове функции обертка, добавленная каждым декоратором, выполняется сверху вниз. @login_required
должен быть ниже любых других декораторов, которые предполагают, что пользователь вошел в систему, чтобы его состояние оценивалось раньше этих других.
@app.route()
всегда должен быть верхним, самым внешним декоратором. В противном случае маршрут будет зарегистрирован для функции, которая не представляет все декораторы.
Более широкий ответ заключается в том, что это зависит от того, что делает каждый из декораторов. Вам нужно подумать о потоке вашей программы и о том, будет ли логично, чтобы одно предшествовало другому.
согласно реализации login_required,
def login_required(func):
@wraps(func)
def decorated_view(*args, **kwargs):
if current_app.login_manager._login_disabled:
return func(*args, **kwargs)
elif not current_user.is_authenticated():
return current_app.login_manager.unauthorized()
return func(*args, **kwargs)
return decorated_view
Вы должны сделать это, как показано ниже.
@login_required
@paginate
def view_function():
pass
предположим, что у вас есть другой декоратор is_admin, чтобы судить, что у пользователя есть права администратора, вы должны сделать это, как показано ниже.
@login_required
@is_admin
def view_function():
pass
В документации Flask указано, что порядок имеет значение, если функция является представлением и имеет декоратор route
. Из документов:
При применении дополнительных декораторов всегда помните, что декоратор route() является самым внешним.
Согласно PEP 318 синтаксис декораторов функций следующий:
@dec2
@dec1
def func(arg1, arg2, ...):
pass
это эквивалентно:
def func(arg1, arg2, ...):
pass
func = dec2(dec1(func))
и dec1 вызывается перед dec2.
Вы можете определить эти функции для проверки следующим образом:
def dec1(func):
print 'dec1'
def dec2(func):
print 'dec2'
@dec2
@dec1
def func():
pass
dec1
dec2
На самом деле это не вызывает никаких ошибок, но если вы сначала используете login_reqired
, а пользователь не вошел в систему, приложение будет обрабатывать данные и разбивать их на страницы после того, как эта функция login_required
сгенерирует прерывание.
Лучшая реализация декоратора login_required в колбе:
@paginate
@login_required
def view_function():
pass
@login_required
над @paginate
-- позвольте мне объяснить, почему... Несмотря на то, что декораторы технически выполняются снизу вверх, вы должны помнить, что когда декоратор выполняется, он возвращает оболочку. В оболочке должны выполняться основные функции декоратора... а оболочки декоратора выполняются сверху вниз.
- person Jimmy Huch; 12.09.2018