在第一篇中,我们讲到了Flask中的Controller和Model,但是一个完整的MVC,没有View怎么行?前端代码如果都靠后台拼接而成,就太麻烦了。本篇,我们就介绍下Flask中的View,即模板。

系列文章

模板

Flask的模板功能是基于Jinja2模板引擎实现的。让我们来实现一个例子吧。创建一个新的Flask运行文件(你应该不会忘了怎么写吧),代码如下:

from flask import Flask
from flask import render_template
app = Flask(__name__)
@app.route('/hello')
@app.route('/hello/')
def hello(name=None):
return render_template('hello.html', name=name)
if __name__ == '__main__':
app.run(host='0.0.0.0', debug=True)

这段代码同上一篇的多URL路由的例子非常相似,区别就是hello()函数并不是直接返回字符串,而是调用了render_template()方法来渲染模板。方法的第一个参数hello.html指向你想渲染的模板名称,第二个参数name是你要传到模板去的变量,变量可以传多个。

那么这个模板hello.html在哪儿呢,变量参数又该怎么用呢?别急,接下来我们创建模板文件。在当前目录下,创建一个子目录”templates”(注意,一定要使用这个名字)。然后在”templates”目录下创建文件”hello.html”,内容如下:

Hello Sample


{% if name %}

Hello {{ name }}!

{% else %}

Hello World!

{% endif %}

这段代码是不是很像HTML?接触过其他模板引擎的朋友们肯定立马秒懂了这段代码。它就是一个HTML模板,根据name变量的值,显示不同的内容。变量或表达式由{{ }}修饰,而控制语句由{% %}修饰,其他的代码,就是我们常见的HTML。

让我们打开浏览器,输入http://localhost:5000/hello/man,页面上即显示大标题”Hello man!“。我们再看下页面源代码

Hello from Flask


Hello man!

果然,模板代码进入了Hello {{ name }}!分支,而且变量{{ name }}被替换为了”man”。Jinja2的模板引擎还有更多强大的功能,包括for循环,过滤器等。模板里也可以直接访问内置对象如request, session等。对于Jinja2的细节,感兴趣的朋友们可以自己去查查。

模板继承

一般我们的网站虽然页面多,但是很多部分是重用的,比如页首,页脚,导航栏之类的。对于每个页面,都要写这些代码,很麻烦。Flask的Jinja2模板支持模板继承功能,省去了这些重复代码。让我们基于上面的例子,在”templates”目录下,创建一个名为”layout.html”的模板:

Hello Sample 
 
{% block body %}
{% endblock %}



再修改之前的”hello.html”,把原来的代码定义在{% block body %}中,并在代码一开始”继承”上面的”layout.html”:

{% extends "layout.html" %}
{% block body %}
{% if name %}

Hello {{ name }}!

{% else %}

Hello World!

{% endif %}

{% endblock %}

打开浏览器,再看下http://localhost:5000/hello/man页面的源码。

Hello Sample


Hello man!



你会发现,虽然render_template()加载了”hello.html”模板,但是”layout.html”的内容也一起被加载了。而且”hello.html”中的内容被放置在”layout.html”中{% block body %}的位置上。形象的说,就是”hello.html”继承了”layout.html”。

HTML自动转义

我们看下下面的代码:

@app.route('/')
def index():
return '
 
 

   Hello %s 
 
' % ' 
 Flask'


打开页面,你会看到”Hello Flask”字样,而且”Flask”是斜体的,因为我们加了标签。但有时我们并不想让这些HTML标签自动转义,特别是传递表单参数时,很容易导致HTML注入的漏洞。我们把上面的代码改下,引入”Markup”类:

from flask import Flask, Markup
app = Flask(__name__)
@app.route('/')
def index():
return Markup('
 
 

   Hello %s 
 
') % ' 
 Flask'


再次打开页面,标签显示在页面上了。Markup还有很多方法,比如escape()呈现HTML标签, striptags()去除HTML标签。这里就不一一列举了。

我们会在Flask进阶系列里对模板功能作更详细的介绍。

本文中的示例代码可以在这里下载。