一、模版:存放位置、读取优先级
到处放,但根目录下的优先。
- 模版文件夹 = 主py的模版文件夹 + 蓝图的模版文件夹
- 主py的模版文件夹 = 主py同级的templates 文件夹
- 蓝图的模版文件夹 = 蓝图py同级的某个文件夹, 其名由创建蓝图实例时的参数指定(也可以不指定,则
render_template()
函数就不在这个蓝图下查找模版文件 )
- 无论在主py还是在蓝图py的响应函数里, 使用render_template() 函数返回模版时, Flask都会在所有模版文件夹中查找模版文件, 但是以主py的模版文件夹优先
模版文件夹(到处都有)
# 目录结构
├── bp_test
│ ├── static
│ └── templates # 蓝图bp_test的模版文件夹,在创建蓝图时声明
│ └── my.html
├── bp_toto
│ ├── bp_2.py
│ ├── static
│ └── templates # 蓝图bp_toto的模版文件夹,在创建蓝图时声明
│ └── my2.html
├── static
├── templates # 主py的模版文件夹,有默认值不用声明
│ └── my.html
└── t.py
# 创建Flask时不需要指定模版文件夹名,因为有缺省值
app = Flask(__name__)
# 创建蓝图实例时需要指定模版文件夹名,因为没有缺省值
# 如果不设为templates,设为moban,也是作为模版文件夹适用"到处乱找"的
user_main = Blueprint("user_main", __name__,
template_folder="templates") # 设置模版文件名名


返回渲染(render)后的模版
在响应函数中返回模版文件需要用到render_template()
函数,这个函数使用前需要单独导入,具体来说:
from flask import Flask
from flask import render_template # 渲染模版
app = Flask(__name__)
@app.route('/')
def root():
return render_template('index.htm') # 模版中的url_for()这些函数会被解析
- 把模版放在蓝图下面,有利于蓝图模块的独立性(我比较推荐 ),但是容易导致模版文件重名的问题。建议蓝图的模版文件名前面加上蓝图名前缀,即可完美解决。
二、静态资源:引用
跟模版一样,也可以到处放;但是没有优先级问题。
- 静态资源文件夹 = 主py静态资源文件夹 + 蓝图的静态资源文件夹
- 主py的默认根目录static,蓝图的需要设置,一般是蓝图目录下的static
以上两个与模版文件夹一致
- 引用使用
url_for()
函数,第一个参数是静态资源文件夹的路径,第二个参数的资源的文件名(需要注明filename=''
)- 因为设置了路径,因此不存在重名、优先级的问题
# 创建蓝图时声明静态资源文件夹和模版文件夹
user_main = Blueprint("user_main", __name__,
template_folder="templates", # 设置模版文件夹
static_folder="static") # 设置静态资源文件夹
静态资源一般放置:*.js
、*.css
、img
这些文件的,模版中使用url_for()
函数指定资源位置(加载静态资源)。你如果硬要把html
也放进static
里去也行,但是就不能用url_for()
函数指定静态资源位置了,在垮蓝图引用时会不方便)。
在模版中调用静态资源
由于数据表现还在在客户端用vue.js 来得实际,在后端就不要用太多的模版渲染折磨服务器CPU了。模版渲染就处理一下静态资源好了。
- 第一个参数是静态资源文件夹名,如果资源在蓝图下面,还要加蓝图的endpoint前缀(就是创建蓝图实例时给的一个字符串参数 )
- 第二个参数是注明关键字的参数:
filename=''
,注明静态资源的文件名
需要特别说明的是:
即使是蓝图中的响应函数返回蓝图自己的模版文件夹中的模版文件,且文件里使用url_for()
引用蓝图自己的静态资源,这个url_for()
的第一个参数也要在static
前面加模版的endpoint
前缀!
很好理解啊,无论
url_for()
所在的文件在哪里,它引用资源时都要指定蓝图endpoint
.static
的路径
<!--css放最前面-->
<link rel="stylesheet" href="{{ url_for('static', filename='bootstrap.css') }}">
<!--body部分-->
<a href="{{ url_for('salut') }}">链接</a> # 好处是路由可以随便改,不影响代码. 这里的参数是相应函数名(不带括号的)
<!--js放最后面-->
# 一般直接在根目录的static中加载
<script src="{{ url_for('static', filename='jquery.min.js') }}"></script>
# 如果要从蓝图的static中加载,需要加蓝图名前缀
<script src="{{ url_for('蓝图实例名.static', filename='vue.js') }}"></script>
<script src="{{ url_for('static', filename='bootstrap.js') }}"></script>
响应函数直接把html作为静态资源返回(不推荐)
还是可以把html
直接放在static
文件夹中,然后作为静态资源返回,此时需要调用app.send_static_file()
方法,这个是app的方法,不需要额外导入。但需要注意的是:
- 不能用url_for()函数来引用静态资源
- 静态资源可以直接写路径引用,但是容易出错,特别是跨蓝图引用
- 如果js直接写CDN路径,就不会存在这方面的困扰了
具体来说:
from flask import Flask
app = Flask(__name__)
@app.route('/')
def root():
return app.send_static_file('index.htm') # 返回static文件夹中的index.htm
总结一句
- 静态资源 :因为要指定路径,因此没有优先级的问题
- 模版文件 :在整个app的各种模版文件夹中乱找,有重名的话以主py所属的模版文件夹中的文件优先
三、url_for()跨蓝图引用生成超链接
- 引用格式是:
蓝图endpoint
.响应函数名
- 如果是主py下的响应函数就可以不加前面的
蓝图endpoint.
具体是:
<a href="{{ url_for('蓝图endpoint.响应函数名') }}">链接指向蓝图下的一个路由</a>
<a href="{{ url_for('pombenbp2.root') }}">链接指向蓝图下的一个路由</a>
<a href="{{ url_for('root') }}">链接指向根目录</a>
详情可以在主py的代码中打印所有的endpoint到屏幕
print(app.url_map) # app是Flask的实例
四、关于jinja2{{}}与vue.js{{}}的冲突
避免在vue.js中使用 {{}}
引用变量
# 原来的
<p>{{ 变量名 }}</p>
# 改为
<p v-text='变量名'></p>
网友评论