Flask: 模版

来源:互联网 发布:剑三炮太捏脸数据 编辑:程序博客网 时间:2024/05/22 00:21

  • 引言
  • Jinja2 模版引擎
    • 渲染模版
    • 变量
    • 控制结构
      • 条件控制语句
      • for 循环
      • 包含
      • 继承

引言

模版是一个包含响应文本的文件,其中包含用占位变量表示的动态部分,其具体指只在请求的上下文中才能知道。使用真实值替换变量,再返回最终得到的响应字符串,这一过程称为 渲染 。为了渲染模版, Flask 使用了一个名为 Jinja2 的强大模版引擎。

Jinja2 模版引擎

形式最简单的Jinja2模版就是一个包含响应文本的文件。

示例 1 templates/index.html

<h1>Hello World!</h1>

示例 2 templates/user.html

<h1>Hello, {{ name }}!</h1>

示例2 中包含一个使用变量表示的动态部分 {{ name }}

渲染模版

默认情况下, Flask 在程序文件夹中的 templates 子文件夹中寻找模版。我们将 示例1 和 示例2 分别命名为 index.htmluser.html 存放在 templates 文件夹下。

视图函数对应为:

from flask import Flask, render_template#...@app.route('/')def index():    return render_template('index.html')@app.route('/user/<name>')def user(name):    return render_template('user.html', name=name)

Flask 提供的 render_template 函数把 Jinja2 模版引擎集成到程序中。 render_template 函数的第一个参数是模版的文件名。随后的参数都是键值对, 表示模版中变量对应的真实值。在这段代码中,第二个模版收到一个名为 name 的变量。

视图函数中 name=name 是关键字参数,左边的 name 表示参数名,就是模版中的占位符;右边的 name 是当前作用域中的变量,表示同名参数的值。

变量

示例2 在模版中使用的 {{ name }} 结构表示一个变量,它是一种特殊的占位符, 告诉模版引擎这个位置的值从渲染模版时使用的数据中获取。

Jinja2 能识别所有类型的变量,甚至 列表、字典和对象。在模版中使用变量的一些示例如下:

<p>A vakue from a dictionary: {{ mydict['key'] }}.</p><p>A vakue from a list: {{ mylist[3] }}.</p><p>A vakue from a list, with a variable index: {{ mylist[myintvar] }}.</p><p>A vakue from a object's method: {{ myobj.somemethod() }}.</p>

可以使用 过滤器 修改变量, 过滤器名添加在变量名之后, 中间使用竖线分隔。例如,下述模版以首字母大写形式显示变量 name 值:

Hello, {{ name|capitalize }}

常用过滤器:

过滤器名 说明 safe 渲染值时不转义 capitalize 把值的首字母转换成大写,其他字母转换成小写 lower 把值转换成小写形式 upper 把值转换成大写形式 title 把值中的每个单词的首字母都转成大写 trim 把值的首尾空格去掉 scriptags 渲染之前把值中所有的 HTML 标签都删掉

注意:千万别在不可信的值上使用 safe 过滤器,例如用户在表单中输入的文本。
默认情况下,出于安全考虑, Jinja2 会转移所有变量。例如, 如果一个变量的值为 '<h1>Hello</h1>'Jinja2 会将其渲染成 '&lt;h1&gt;Hello&lt;/h1&gt;',浏览器能显示 h1 元素,但不会进行解释。

控制结构

Jinja2 提供了多种控制结构,可用来改变模版的渲染流程。

条件控制语句

{% if user %}    Hello, {{ user }}{% else %}    Hello, Stranger!{% endif %}

for 循环

<ul>    {% for comment in comments %}        <li>{{ comment }}</li>    {% endfor %}</ul>

宏类似 python 中的函数

{% macro render_comment(comment) %}    <li>{{ comment }}</li>{% endmacro %}<ul>    {% for comment in comments %}        {{ render_comment(comment) }}    {% endfor %}</ul>

包含

需要在多出重复使用的模版代码片段可以写入单独的文件,再包含在所有模块中,以避免重复:

{% include 'common.html' %}

继承

另一种重复使用代码的强大方式是模版集成,它类似与 Python 代码中的类继承。首先, 创建一个名为 base.html 的基模版:

<html><head>    {% block head %}    <title>{% block title%}{% endblock %} - My Application<title>    {% endblock %}</head><body>    {% block body %}    {% endblock %}</body></head>

block 标签定义的元素可在衍生模版中修改。在 base.html 中,我们定义了名为 headtitlebody 的块。注意, title 包含在 head 中。 下面这个示例是基模版的衍生模版:

{% extends "base.html" %}{% block title %}Index{% endblock %}{% block head %}    {{ supper() }}    <style>    </style>{% endblock %}{% block body %}<h1>Hello, World!</h1>{% endblock %}

extends 指令声明这个模版衍生自 base.html。在 extends 指令后, 基模版中的 3 个块被重新定义, 模版引擎会将其插入适当的位置。注意新定义的 head 块, 在基模版中其内容不是空的, 所以使用 super() 获取原来的内容。

原创粉丝点击