В настоящее время у меня есть представление, которое возвращает разные ответы в зависимости от того, является ли пользователь анонимным или нет, я использую:
@app.route("/anonymous")
def anonymous_page():
if current_user.is_anonymous:
return render_template("anonymous_page.html")
return render_template("user_page.html")
Я хочу создать декоратор, назовем его @show_only_to_anonymous
, которая может быть использована в обычной функции представления с одним оператором return, который будет делать что-то вроде этого:
@app.route("/anonymous")
@show_only_to_anonymous
# if the user is anonymous, return the decorated function's view,
# elif the user is NOT anonymous, return "user_page.html"
def anonymous_page():
return render_template("anonymous_page.html")
Я знаю, что есть login_required
декоратор, я пошел посмотреть на исходный код здесь , и он использует LocalProxy
для current_user
под колпаком, попытался повторить это и потерпел неудачу,
Я думаю, что мое понимание структуры flask отсутствует как Я новичок в этом, у кого-нибудь есть идея?
edit: мне удалось заставить ее работать, посмотрев на исходный код flask -login, файл: flask_login/utils.py
, я использовал те же самые функции flask
и werkzeug.local
и другие объекты и создали новый файл в моем проекте, который я назвал custom_decorators.py
и импортировал как модуль в мой файл routes.py
, это содержимое custom_decorators.py
:
from functools import wraps
from werkzeug.local import LocalProxy
from flask import _request_ctx_stack, has_request_context, current_app
current_user = LocalProxy(lambda: _get_user())
def _get_user():
if has_request_context() and not hasattr(_request_ctx_stack.top, 'user'):
current_app.login_manager._load_user()
return getattr(_request_ctx_stack.top, 'user', None)
def show_only_to_anonymous(func):
@wraps(func)
def decorated_view(*args, **kwargs):
if not current_user.is_anonymous:
return current_app.view_functions['show_to_known_users'](*args, **kwargs)
return func(*args, **kwargs)
return decorated_view
сейчас в моем routes.py
Я могу сделать это:
# this page can only be seen by anonymous users
@app.route("/anonymous")
@show_only_to_anonymous
def anonymous_page():
return render_template("anonymous_page.html")
# this will be called if a logged in user goes to mywebsite.com/anonymous:
@app.route("/show_to_known_users")
def show_to_known_users():
return redirect(url_for("user_page.html", code=301))
th решение выглядит немного «хакерским», есть ли лучший способ?