如何在Flask应用程序中设置static_url_path

use*_*617 8 flask

我想做这样的事情:

app = Flask(__name__)
app.config.from_object(mypackage.config)
app.static_url_path = app.config['PREFIX']+"/static"
Run Code Online (Sandbox Code Playgroud)

当我尝试:

print app.static_url_path
Run Code Online (Sandbox Code Playgroud)

我明白了 static_url_path

但是在我使用的模板中url_for('static'),使用jinja2生成的html文件仍然具有默认的静态URL路径/static,缺少PREFIX我添加的路径.

如果我像这样硬编码路径:

app = Flask(__name__, static_url_path='PREFIX/static')
Run Code Online (Sandbox Code Playgroud)

它工作正常.我究竟做错了什么?

Mar*_*ers 7

Flask 在您创建Flask()对象时创建 URL路由.您需要重新添加该路线:

# remove old static map
url_map = app.url_map
try:
    for rule in url_map.iter_rules('static'):
        url_map._rules.remove(rule)
except ValueError;
    # no static view was created yet
    pass

# register new; the same view function is used
app.add_url_rule(
    app.static_url_path + '/<path:filename>',
    endpoint='static', view_func=app.send_static_file)
Run Code Online (Sandbox Code Playgroud)

Flask()使用正确的静态URL路径配置对象会更容易.

演示:

>>> from flask import Flask
>>> app = Flask(__name__)
>>> app.url_map
Map([<Rule '/static/<filename>' (HEAD, OPTIONS, GET) -> static>])
>>> app.static_url_path = '/PREFIX/static'
>>> url_map = app.url_map
>>> for rule in url_map.iter_rules('static'):
...     url_map._rules.remove(rule)
... 
>>> app.add_url_rule(
...     app.static_url_path + '/<path:filename>',
...     endpoint='static', view_func=app.send_static_file)
>>> app.url_map
Map([<Rule '/PREFIX/static/<filename>' (HEAD, OPTIONS, GET) -> static>])
Run Code Online (Sandbox Code Playgroud)


小智 5

接受的答案是正确的,但略有不完整。的确,为了改变static_url_path一个还必须更新应用程序的url_map通过去除现有Rulestatic端点和添加新的Rule与修改后的URL路径。然而,还必须更新_rules_by_endpoint属性url_map

在 Werkzeug 中检查add()底层证券Map方法是有益的。除了在Rule._rules属性中添加一个 new 之外,MapRule通过将其添加到 来索引._rules_by_endpoint。后一种映射是您调用app.url_map.iter_rules('static'). 这也是 Flask 的url_for().

这是一个如何完全重写 static_url_path 的工作示例,即使它是在 Flask 应用程序构造函数中设置的。

app = Flask(__name__, static_url_path='/some/static/path')

a_new_static_path = '/some/other/path'

# Set the static_url_path property.
app.static_url_path = a_new_static_path

# Remove the old rule from Map._rules.
for rule in app.url_map.iter_rules('static'):
    app.url_map._rules.remove(rule)  # There is probably only one.

# Remove the old rule from Map._rules_by_endpoint. In this case we can just 
# start fresh.
app.url_map._rules_by_endpoint['static'] = []  

# Add the updated rule.
app.add_url_rule(f'{a_new_static_path}/<path:filename>',
                 endpoint='static',
                 view_func=app.send_static_file)

Run Code Online (Sandbox Code Playgroud)