如何将装饰器应用于烧瓶中的所有蓝图URL

时间:2016-05-19 12:22:10

标签: python flask flask-login

我有蓝图和一些网址功能,

admin_bp = Blueprint('admin', __name__)

@admin_bp.route('/dashboard', methods=['GET', ])
@flask_login.login_required
def dashboard():

    context = {}

    page = 'admin/dashboard.html'
    return render_template(page, **context)

@admin_bp.route('/deny', methods=['GET', ])
@flask_login.login_required
def deny():
    return 'hey bro you dont belong here'

我不想为此蓝图下的所有网址功能复制粘贴@flask_login.login_required装饰器。有没有更好的方法可以为所有蓝图网址应用装饰器?

3 个答案:

答案 0 :(得分:3)

您可以添加before_request()作为将在视图中的每个请求之前运行的函数。

然后,您将需要添加装饰器以向before_request函数注入附加功能。您将要导入login_required装饰器,以确保每个端点都需要一个登录用户。该装饰器是flask_login库的一部分。

由于您的视图似乎是管理员的一部分,因此我还建议您使用before_request之类的东西向您的@role_required('admin')函数添加自定义装饰器。该装饰器的功能将存在于其他地方并被导入。

@admin_bp.before_request
@login_required
def before_request():
    """ Protect all of the admin endpoints. """
    pass 

答案 1 :(得分:0)

如何先检查用户:

from flask.ext.login import current_user


@admin_bp.before_request
def check_user():
    if not current_user.is_authenticated():
        abort(401)

# your other functions without `@flask_login.login_required`

答案 2 :(得分:0)

子类Blueprint的子类,并覆盖route方法。

import flask

class MyBlueprint(flask.Blueprint):
  def route(self, rule, **options):
    def decorator(f):
      # these lines are copied from flask.Blueprint.route
      endpoint = options.pop("endpoint", f.__name__)
      self.add_url_rule(rule, endpoint, f, **options)

      # At this point flask.Blueprint.route simply returns f.
      # But you can nest a decorator.
      def inner(*args, **kwargs):
        # stuff you want to do before each request goes here
        try:
          result = f(*args, **kwargs)
          # stuff you want to do on successful responses (probing status, headers, etc.) goes here
        except Exception as e:
          # stuff you want to do on error responses goes here
          raise
      return inner

现在在您的蓝图中使用新的子类:

-v1_blueprint = Blueprint('v1', __name__)
+v1_blueprint = MyBlueprint('v1', __name__)

无需更改单个路线。

这种方法的缺点是它从Flask内部复制代码。如果flask.Blueprint.route的实现要在将来的版本中更改,则在升级Flask时,您需要将MyBlueprint与之同步。