初学 Flask 的人都知道, Flask 的模板文件默认放在 “templates” 文件夹下, 静态资源文件放在 “static” 目录下, 只要照着规矩走, 一点事都没有.
但是为了和我的历史项目结构保持一致性 (加上强迫症), 对 Flask 的默认路径不喜欢, 想把文件这样放:
myproject/
|-layout/ # 原 templates 目录
|-index.html
|-res/ # 原 static 目录
结果意想不到地踩了很多坑, 花了一星期的时间终于弄清楚了.
本文是为了帮大家 (轻松) 理解 Flask 的 static_folder
参数的作用.
为了方便理解, 本文通过一个例子讲解.
假设测试项目的目录结构如下:
myproject/
|-A/
|-B/
|-b.js
|-a.js
|-index.html # 启动界面
|-launch.py # 启动脚本
|-C/
|-c.js
|-d.js
其中每个 js 文件都是测试脚本, 里面就非常简单的一句话:
console.log('x.js') // x 填对应的文件名
launch.py 测试代码:
# A/launch.py
from flask import Flask, render_template
app = Flask(
__name__,
template_folder='.', # 表示在当前目录 (myproject/A/) 寻找模板文件
static_folder='../', # 表示为上级目录 (myproject/) 开通虚拟资源入口
static_url_path='', # 这是路径前缀, 个人认为非常蛋疼的设计之一, 建议传空字符串, 可以避免很多麻烦
)
@app.route('/')
def main():
return render_template(
'index.html'
)
if __name__ == '__main__':
app.run()
index.html 测试代码:
<script src="d.js">script>
<script src="../d.js">script>
<script src="../../d.js">script>
<script src="../../../d.js">script>
<script src="a.js">script>
<script src="A/a.js">script>
<script src="A/B/b.js">script>
<script src="C/c.js">script>
注意, 在开始测试时, 打开浏览器的开发者模式, 并在 network 选项卡把 “Disable cache” 勾选上:
(这样可以避免浏览器使用缓存的测试文件, 避免上次测试结果干扰下次测试.)
测试结果:
解释一下上面的结果:
<script src="d.js">script>
<script src="../d.js">script>
<script src="../../d.js">script>
<script src="../../../d.js">script>
<script src="a.js">script>
<script src="A/a.js">script>
<script src="A/B/b.js">script>
<script src="C/c.js">script>
结论:
Flask.__init__()
中的 static_folder
参数为准static_folder
设为 “…/” 就是为了能够让 Flask 以 myproject/ 为虚拟资源的入口顺便再举一个例子, 我把 static_folder="../"
改为 static_folder="."
看看会发生什么:
# A/launch.py
from flask import Flask, render_template
app = Flask(
__name__,
template_folder='.', # 表示在当前目录 (myproject/A/) 寻找模板文件
static_folder='.', # 表示为当前目录 (myproject/A/) 开通虚拟资源入口
static_url_path='',
)
@app.route('/')
def main():
return render_template(
'index.html'
)
if __name__ == '__main__':
app.run()
测试结果:
[外链图片转存失败(img-CXeoZWKh-1563030961554)(https://i.loli.net/2019/04/17/5cb71a3588420.png)]
解释一下上面的结果:
<script src="d.js">script>
<script src="../d.js">script>
<script src="../../d.js">script>
<script src="../../../d.js">script>
<script src="a.js">script>
<script src="A/a.js">script>
<script src="A/B/b.js">script>
<script src="C/c.js">script>
相信大家从上述例子中, 也能对 static_folder
心里有个底了.
当然 static_url_for
这个参数为什么传空字符串我还没有谈, 总之加上这货才是完成了 Flask 的连环坑.
我这里简单讲一下, static_url_for
缺省值是 None, 也就是会在实例化完成后解释. 它的作用是每当我们从虚拟资源目录入口寻找资源时, 自动帮我们定位到资源目录下的 “static” 文件夹中查找 (不管这个文件夹是否存在). 而当我们在初始化 Flask 实例时给它赋值空字符串, 就能避免它自作聪明了.