购买
下载掌阅APP,畅读海量书库
立即打开
畅读海量书库
扫码下载掌阅APP

4.3 控制语句

在模板中,也存在if判断和for循环等控制语句。所有的控制语句都是放在{% %}中间的,并且在控制语句结束后,要加入相应的结束语句。下面对if判断语句和for循环语句分别进行讲解。

4.3.1 if判断语句

Jinja2中的if判断语句和Python中的if判断语句非常类似,可以使用关系运算符>、<、>=、<=、==、!=来进行判断,也可以通过and、or、not来进行逻辑操作。我们首先创建一个视图函数if_statement,代码如下。

    @app.route("/if")
    def if_statement():
        age = 18
        return render_template("if.xhtml",age=age)

以上代码定义了一个age变量,并且把这个age传给了if.html模板。在if.html模板中,可以根据age的大小判断是否成年。if.html模板的代码如下。

    <!DOCTYPE html>
    <html lang="en">
    <head>
      <meta charset="UTF-8">
      <title>if语句</title>
    </head>
    <body>
    {% if age > 18 %}
        <div>您已成年!</div>
    {% elif age < 18 %}
        <div>您未成年!</div>
    {% else %}
        <div>您刚成年!</div>
    {% endif %}
    </body>
    </html>

因为在视图函数中给age赋值为18,所以在模板中会匹配到以下代码。

    <div>您刚成年!</div>

在浏览器中访问http://127.0.0.1:5000/if,也可以看到显示的是“您刚成年!”,如图4-5所示。

图4-5 模板中使用if判断语句

仔细阅读if.html模板代码可以发现,在if语句结束后,需要添加endif关闭if代码块,这跟Python中的用法是有点不同。

注意

Jinja2中的代码缩进只是为了更加方便阅读,任何缩进都不是必需的。

4.3.2 for循环语句

Jinja2中的for循环与Python中的for循环也非常类似,Jinja2中的for循环只是比Python中的for循环多了一个endfor代码块。我们先来实现一下视图函数for_statement,代码如下。

    @app.route("/for")
    def for_statement():
       books = [{
           "name": "三国演义",
           "author": "罗贯中",
           "price": 100
       },{
           "name": "水浒传",
           "author": "施耐庵",
           "price": 99
       },{
           "name": "红楼梦",
           "author": "曹雪芹",
           "price": 101
       },{
           "name": "西游记",
           "author": "吴承恩",
           "price": 102
       }]
       return render_template("for.xhtml",books=books)

在for_statement视图函数中,首先创建了一个books变量,books是一个列表,里面存放的是图书信息的字典,然后渲染给for.html模板。接下来在模板文件中循环这个列表,代码如下。

因为在table表格标签中,一个tr标签代表表格中的一行,所以在tr外面加了一个for循环,去循环这个books列表。在tr下面,一个td代表一列,每列从book中获取对应的数据,分别是书名、作者、价格。在浏览器中访问http://127.0.0.1:5000/for,显示结果如图4-6所示。

图4-6 Jinja2 for循环

如果被循环的序列(如以上代码中的books)中没有元素,那么可以使用else来处理。通常我们在浏览网页时,如果某个网页没有数据,则会显示“无数据”。我们在以上代码中的for.html模板加上else,来实现一个类似的需求,代码如下。

    ...
    {% for book in books %}
     <tr>
       <td>{{ book.name }}</td>
       <td>{{ book.author }}</td>
       <td>{{ book.price }}</td>
     </tr>
    {% else %}
     <tr>
       <td colspan="3" style="text-align: center;">无数据</td>
     </tr>
    {% endfor %}
    ...

在books中无数据的情况下,会执行到else中,可以将for_statement视图函数的books修改为一个空的列表,代码如下。

    @app.route("/for")
    def for_statement():
        books = []
        return render_template("for.xhtml",books=books)

此时再在浏览器中访问http://127.0.0.1:5000/for,可以看到页面会显示“无数据”,如图4-7所示。

图4-7 显示页面无数据

Jinja2中的for循环中还内置了许多好用的变量。如要获取当前循环到第几次了,可以通过loop.index来实现。我们还是以for_statement视图函数为例,首先将books变量恢复成以下形式。

    books = [{
        "name": "三国演义",
        "author": "罗贯中",
        "price": 100
    },{
        "name": "水浒传",
        "author": "施耐庵",
        "price": 99
    },{
        "name": "红楼梦",
        "author": "曹雪芹",
        "price": 101
    },{
        "name": "西游记",
        "author": "吴承恩",
        "price": 102
    }]

然后在for.html模板中给图书表格新增一个名为序号的列,用loop.index来显示每行的序号,修改后的for.html模板中的table代码如下。

    <table>
      <thead>
        <tr>
          <th>序号</th>
          <th>书名</th>
          <th>作者</th>
          <th>价格</th>
        </tr>
      </thead>
      <tbody>
        {% for book in books %}
          <tr>
            <td>{{ loop.index }}</td>
            <td>{{ book.name }}</td>
            <td>{{ book.author }}</td>
            <td>{{ book.price }}</td>
          </tr>
        {% else %}
          <tr>
            <td colspan="3" style="text-align: center;">无数据</td>
          </tr>
        {% endfor %}
      </tbody>
    </table>

通过以上代码可以看到,在thead标签中新增了一个叫作序号的表头,tbody中新增了一个叫作loop.index列,loop.index在每次循环时,会显示当前循环的次数,即代表第几行。在浏览器中访问http://127.0.0.1:5000/for,可以看到如图4-8所示的效果图。

图4-8 带有序号的循环

除loop.index外,Jinja2中的for循环中还提供了如表4-2所示的变量。

表4-2 for循环中的变量

表4-2中的13个变量中,只有loop.cycle和loop.changed是函数,其余都是变量。这里再做两个案例来讲解loop.cycle和loop.changed的用法。

(1)loop.cycle:假设现在有一个需求,需要针对table标签中行号为奇数的tr标签添加odd类,行号为偶数的tr标签添加even类,可以通过以下代码实现。

    {% for book in books %}
        <tr class="{{ loop.cycle('odd', 'even') }}">
        <td>{{ loop.index }}</td>
        <td>{{ book.name }}</td>
        <td>{{ book.author }}</td>
        <td>{{ book.price }}</td>
        </tr>
    {% endfor %}

在循环books的过程中,loop.cycle也会不断地在odd和even两个变量中循环,从而实现奇数使用odd类,偶数使用even类。

(2)loop.changed:假设现在想要知道当前循环的book.name是否和上次循环的一致,可以通过loop.changed实现,代码如下。

    {% for book in books %}
        <tr>
        <td>{{ loop.index }}</td>
        <td>{{ book.name }}</td>
        <td>{{ book.author }}</td>
        <td>{{ book.price }}</td>
        <td>{{ loop.changed(book.name) }}</td>
        </tr>
    {% endfor %}

Jinja2模板的for循环不存在break和continue来中断循环的语句,这一点是和Python中的for循环最大的区别,另外Jinja2中只有for循环,不存在while循环,读者在使用时尤其要注意这两点。 8PbCdNfukn2Lc22E0Y/tHDIsBkNBnBG4LMB6St73e2aP+8CMm0bTDKl1cEAd4uy6

点击中间区域
呼出菜单
上一章
目录
下一章
×

打开