从没有url前缀的蓝图提供静态文件

时间:2013-10-04 08:17:04

标签: python static-files flask

对于开发,我想从blueprint的静态文件夹中提供静态文件。但是,我不想通过蓝图的url前缀加载所有文件。是否有可能配置flask,所以它查找所有蓝图的静态文件夹并返回它找到的第一个文件? 这样做的原因是,当我部署应用程序时,构建过程将拉取我们蓝图的所有文件并将它们放入一个单独的文件夹(类似于Django的collectstatics)。

换句话说,我有2个蓝图:foobar

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子文件夹中的所有js文件都可以从网址/static/js/file.js获得。这可能吗?

1 个答案:

答案 0 :(得分:2)

您不能使用默认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

当烧瓶与您的网址匹配以进行规则时,首先匹配并返回。在这种情况下,它返回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一样简单。