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

时间:2014-11-03 20:08:28

标签: flask

我想做这样的事情:

app = Flask(__name__)
app.config.from_object(mypackage.config)
app.static_url_path = app.config['PREFIX']+"/static"

当我尝试:

print app.static_url_path

我得到了正确的static_url_path

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

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

app = Flask(__name__, static_url_path='PREFIX/static')

工作正常。我做错了什么?

2 个答案:

答案 0 :(得分:7)

Flask在您创建Flask()对象时创建网址。您需要重新添加该路线:

# 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)

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

演示:

>>> 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>])

答案 1 :(得分:0)

可接受的答案是正确的,但略微不完整。的确,要更改static_url_path,还必须通过删除url_map端点的现有Rule并添加新的{{1}来更新应用程序的static。 }和修改后的网址路径。但是,还必须更新Rule上的_rules_by_endpoint property

研究Werkzeug中的add() method on the underlying Map具有指导意义。除了向其url_map属性添加新的Rule之外,._rules还通过将Map添加到Rule来为._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)