如何将装饰器应用于每个 Flask 视图

Posted

技术标签:

【中文标题】如何将装饰器应用于每个 Flask 视图【英文标题】:How to apply decorator to every Flask view 【发布时间】:2014-06-01 23:04:43 【问题描述】:

我有一个装饰器(称为deco),我想将其应用于我的 Flask 应用程序中的每个视图,以便修改响应标头以避免 IE 的兼容模式 (res.headers.add("X-UA-Compatible", "IE=Edge")。我喜欢用它

@app.route('/')
@deco
def index():
    return 'Hello world'

我目前使用 Flask 的子类来创建应用程序(修改 jinja 行为)

class CustomFlask(Flask):
    jinja_options = ...

app = CustomFlask(__name__, ...)

有没有办法可以修改 CustomFlask 以将 deco 装饰器应用于所有响应?

【问题讨论】:

你到底想在这里做什么?您要解决的用例是什么?这感觉就像XY problem,如果我见过的话。 适用于 IE。我更新了问题。 【参考方案1】:

要为每个传出响应添加标头,请改用@Flask.after_request hook:

@app.after_request
def add_ua_compat(response):
    response.headers['X-UA-Compatible'] = 'IE=Edge'
    return response

有一个Flask extension 正是做到了这一点;注册钩子并添加标题。

【讨论】:

谢谢,这就是我想要的。很抱歉造成混乱。 请注意,从 Flask 0.7 开始,after_request 可能不会被调用。在这种情况下,编写一个 WSGI 中间件可能更合适。 @RobYoung:是什么让你认为它没有被调用?我已经在 0.7 的生产环境中使用了它,没有任何问题。您是否正在返回流式响应? @MartijnPieters,也许 Rob 想到了:rallion.bitbucket.org/explorations/flask_tutorial/api/…【参考方案2】:

您可以考虑编写一个自定义的WSGI 中间件。您可以捕获所有应用程序的响应并根据需要增加标头。 quickstart 讨论了如何挂钩中间件,并且不乏 WSGI 教程关于如何将标头添加到 start_response

【讨论】:

我看不出可插入视图在这里有什么帮助;我不确定为什么 OP 认为装饰器会这样做。 @MartijnPieters 装饰器可能不是必需的,我只是用它来修改响应头。 @BirdJaguarIV:为什么不使用after_request hook 呢?这就是我在这种情况下使用的方法。 @BirdJaguarIV 您可以考虑重新表述您的问题,提供有关您想要对响应做什么的详细信息。

以上是关于如何将装饰器应用于每个 Flask 视图的主要内容,如果未能解决你的问题,请参考以下文章

装饰器的顺序在 Flask 视图中是不是重要?

Flask特殊装饰器

Flask--视图增加多装饰器

Flask 给视图函数增加装饰器

11Flask实战第11天:视图使用装饰器

你如何使用 Flask-Login 和自定义 Python 装饰器来分配用户权限?