专否 写文章

BlackA,Talk is cheap,Show me the code.

Oct 29, 2018
Follow

Flask 学习笔记 #5 -- Jinja2模板 II

我们在上一节中学习了Jinja2模板引擎的基本用法,并用Jinja2模板生成了一些简单的HTML页面。但是Jinja2的强大功能不止于此,这一节中我们将会继续学习Jinja2中的控制语句。

1、if 语句

Jinja2提供了类似Python语法的 if 语句,用来控制渲染模板的哪一部分,这有点像C语言中的条件编译,但是远比条件编译的功能强大。我们先来看一个例子,在这个例子中,我们仿照V2EX的登录功能,当用户未登录时,在浏览器的右上角显示 “首页”、“注册”、和 ”登录“ 三个按钮,当用户登录后,显示 “首页”、“用户名”、”设置“、和 “登出” 四个按钮:

这次我们先来看看Python程序代码:

from flask import Flask,render_template
app = Flask(__name__)

# 因为我们还没有学习cookie,所以这里使用is_login来模拟用户是否登录
# 当is_login的值为1时,代表已经登录,为0代表未登录
@app.route("/<int:is_login>/")
def index(is_login):
    if is_login == 1:
        # 如果用户已经登录,得到用户对应的信息,并传给模板渲染
        # 因为我们还没有学习数据库操作,所以这里只使用固定的值来渲染模板
        user = {"username" : "blacka","age" : 18}
        return render_template("index.html",user = user)
    else:
        # 如果用户没有登录,则仅仅渲染模板而不传递用户的信息
        return render_template("index.html")

if __name__ == "__main__":
    app.run(debug = True)

在上面这个程序中,我们先确定用户是否登录,如果用户已经登录,我们就从数据库中查询对应的用户信息,并把用户信息传递给模板进行渲染;如果用户没有登录,我们就什么也不传递,直接渲染模板,这就要我们的模板可以判断flask程序是否传递了需要渲染的用户信息,即user这个字段值是否为空,如果为空就说明用户没有登录,显示 “首页”、“注册”、和 ”登录“ 三个按钮,反之说明用户已经登录,显示 “首页”、“用户名”、”设置“、和 “登出” 四个按钮:

<!DOCTYPE html>
<html lang="zh-cn">
    <head>
        <meta charset="utf-8">
        <title>Hello</title>
    </head>
    <body>

        {# if 语句使用一个大括号和一个井号扩起 #}
        {% if user %}

            {# 如果定义了user这个变量就渲染这里 #}
            <a href="#">首页</a>
            <a href="#">{{user.username}}</a>
            <a href="#">设置</a>
            <a href="#">登出</a>
        {% else %}
            {# 如果没有定义就渲染这里 #}
            <a href="#">首页</a>
            <a href="#">注册</a>
            <a href="#">登录</a>

        {# 使用endif来标识if语句块的结束 #}
        {% endif %}

    </body>
</html>

下面是这个程序的运行结果:

提供上面这个例子我们可以看出 if 语句的一般语法格式:

{% if 条件1 %}
    语句块1
[ {% elif 条件2 %} ]
    [ 语句块2 ]
...
[ {% else %} ]
    [ 语句块3 ]
{% endif %}

在Jinja2中控制语句(if、for)使用 ”{%“ 和 ”%}“ 括起来,由 ”[“ 和 "]"括起来的部分代表是可选的,因为HTML会忽略源文件中的空白,所以无法使用缩进来确定 if 语句的结尾,需要使用 “{% endif %}” 表示 if 语句的结尾。

if 后面的条件可以写类似Python的条件表达式,具体的细节可以参考官方文档

2、for 循环

Jinja2不仅仅提供了 if 语句用来控制条件,还提供了 for 语句用来循环的渲染某一个语句,当我们需要动态的生成一个列表或者表格的时候,使用 for 循环可以化简我们的工作量:

# 当用户访问/books/时在浏览器上显示书籍信息的列表
from flask import Flask,render_template
app = Flask(__name__)

@app.route("/books/")
def show_books():

    # 一个字典列表存放书籍
    books = [
            {
                "姓名" : "红楼梦",
                "作者" : "曹雪芹",
                "价格" : 109
            },
            {
                "姓名" : "三国演义",
                "作者" : "罗贯中",
                "价格" : 120
            },
            {
                "姓名" : "水浒传",
                "作者" : "施耐庵",
                "价格" : 119
            },
            {
                "姓名" : "西游记",
                "作者" : "吴承恩",
                "价格" : 108
            }
    ]
    # 传递字典列表给Jinja2框架
    return render_template("books.html",books = books)

if __name__ == "__main__":
    app.run(debug = True)
<!DOCTYPE html>
<html lang="zh-cn">
    <head>
        <meta charset="utf-8">
        <title>书籍信息</title>
    </head>
    <body>
        <!-- 无序列表 -->
        <ul>
            {# 循环遍历列表,语法格式与python类似 #}
            {% for book in books %}
                <!-- 列表项 -->
                <li>
                    {# 循环遍历字典,除了items()方法外, #}
                    {# 还可以使用keys()、values()、 #}
                    {# iteritems()、iterkeys()等字典方法 #}
                    {% for k,v in book.items() %}
                        {{k}} : {{v}}
                    {% endfor %}
                </li>
            {% endfor%}
        </ul>	
    </body>
</html>

这个例子虽然有些臃肿,但是它展示如何使用for 循环遍历列表和字典,下面是代码的运行效果:

另外,Jinja2还内置了一些循环变量,可以在循环中访问它们:

# loop.index	            当前循环迭代的次数(从 1 开始)
# loop.index0	            当前循环迭代的次数(从 0 开始)
# loop.revindex	            到循环结束需要迭代的次数(从 1 开始)
# loop.revindex0            到循环结束需要迭代的次数(从 0 开始)
# loop.first	            如果是第一次迭代,为 True 。
# loop.last	            如果是最后一次迭代,为 True 。
# loop.length	            序列中的项目数。
# loop.cycle	            在一串序列间期取值的辅助函数。

我们可以通过 loop.first 变量实现书籍名字的黑体:

{% for k,v in book.items() %}
    {% if loop.first %}
        <b> {{k}} : {{v}} </b>
    {% else %}
        {{k}} : {{v}}
    {% endif %}
{% endfor %}


***  最后,根据官方文档的建议,应在模板中尽量少的使用if 和 for 等控制语句。 ***

喜欢这个文章 | 分享 | 新建跟帖