从没有URL前缀的蓝图中提供静态文件
问题内容:
为了进行开发,我想从蓝图的静态文件夹中提供静态文件。但是,我不想通过蓝图的url前缀加载所有文件。是否可以配置flask,以便它在所有蓝图的静态文件夹中查找并返回找到的第一个文件?这样做的原因是,当我部署该应用程序时,构建过程会将所有蓝图文件拉入到单独的文件夹中(类似于Django的collectstatics)。
换句话说,我有2个蓝图:foo
和bar
:
app
+--- foo
| +--- assets
| | +--- css
| | |
| | +--- js
| +
| |
| +--- __init__.py: foo_blueprint = Blueprint('foo', __name__, static_folder='assets')
|
+--- bar
+
|
+--- __init__.py: bar_blueprint = Blueprint('bar', __name__, static_folder='assets')
我希望js
可以从url获得特定子文件夹中的所有js文件/static/js/file.js
。这可能吗?
问题答案:
您不能使用默认flask
机制。
在您的示例中,您将为静态forlder创建3条规则:
Rule "/assets/<path:filename>" for "static" endpoint
Rule "/assets/<path:filename>" for "foo.static" endpoint
Rule "/assets/<path:filename>" for "bar.static" endpoint
当flask将匹配您的URL进行统治时,将进行第一次匹配并返回它。在这种情况下,它返回static
端点规则。之后将为此端点调度功能,例如一个文件夹。
PS。我不确定到底是static
终点,还是更好的检查Map.update
方法。
但是您始终可以编写自己的请求描述符,该描述符将查看蓝图文件夹:
class MyApp(Flask):
def static_dispatchers(self):
yield super(MyApp, self).send_static_file
for blueprint in self.blueprints.values():
yield blueprint.send_static_file
def send_static_file(self, filename):
last_exception = None
for static_dispatcher in self.static_dispatchers():
try:
return static_dispatcher(filename)
except NotFound as e:
last_exception = e
raise last_exception
PS。此示例不包括蓝图注册序列,因为它存储在dict中。
但是,如果您有两个同名文件,则将处理第一个文件。例如,如果您具有下一个结构:
/static
/static/app.js "console.log('app');"
/foo/static/app.js "console.log('foo app');"
/foo/static/blue.js "console.log('foo blue');"
/foo/static/foo.js "console.log('foo self');"
/bar/static/app.js "console.log('bar app');"
/bar/static/blue.js "console.log('foo blue');"
/bar/static/bar.js "console.log('bar self');"
并在页面中包含脚本:
<script src="{{ url_for('static', filename='app.js') }}"></script>
<script src="{{ url_for('foo.static', filename='app.js') }}"></script>
<script src="{{ url_for('bar.static', filename='app.js') }}"></script>
<script src="{{ url_for('foo.static', filename='blue.js') }}"></script>
<script src="{{ url_for('bar.static', filename='blue.js') }}"></script>
<script src="{{ url_for('foo.static', filename='foo.js') }}"></script>
<script src="{{ url_for('bar.static', filename='bar.js') }}"></script>
您将获得下一个结果:
app
app
app
foo blue (or bar blue)
foo blue (or bar blue)
foo self
bar self
对于js和CSS,可以使用相同的路径连接文件,但不能对图像执行此操作。
但是,我更喜欢为每个蓝图使用唯一的URL前缀,因为使用它很简单url_for
。