0


Flask Web——Jinjia2模板的使用

静态模板的使用

Jinjia2是Flask使用的html渲染模板,Jinjia原意为日本的神社,英文为temple,与模板的英文template相近,故取名jinjia。
首先先演示如何在flask代码中展示静态的html,方法是使用flask库中的

render_template()

方法,其参数为template(默认为template,也可以通过参数修改)文件夹中的“index.html”,通过这种方式,可以在进入指定UML之后,访问html页面。

@app.route('/')defhello_world():# put application's code herereturn render_template("index.html")

在这里插入图片描述
👇index.html的html页面代码:

<!DOCTYPEhtml><htmllang="en"><head><metacharset="UTF-8"><title>首页</title></head><body><h1>这是首页</h1></body></html>

在这里插入图片描述

渲染变量——传递参数

HTML中有些数据需要动态地从数据库中加载,不能直接写死在HTML页面中,在视图函数中可以将数据提取好,再通过Jinjia2传递参数的方式将数据在视图函数中通过render_template()(render的本意即为渲染)传递给HTML。在html中使用双花括号

{{ hobby }}

即可使用变量,此处的hobby即为在视图函数中使用render_template传递过来的变量。此外,字典的键值和对象的属性在模板中都可以通过点(.)来传递, 还可以通过

["属性名"]

的方式传递, 二者的区别在于, 使用

.

先查看变量是否为字典, 再查看是否为对象, 都不是则返回undefined对象, 而使用方括号则字典和对象的寻找顺序相反.

classUser:def__init__(self, username, email):
        self.username = username
        self.email = email

@app.route('/variable')defvariable():
    hobby ="游戏"
    person ={"name":"张三","age":18}
    user = User("里斯","[email protected]")return render_template("variable.html", hobby=hobby,person=person,user=user)

👆注意, 如果传递参数时, 名字出错了, 则在html页面不会显示, 推测是因为没有打开debug模式. 👇

<!DOCTYPEhtml><htmllang="en"><head><metacharset="UTF-8"><title>变量使用</title></head><body><h1>我的兴趣爱好是:{{ hobby }}</h1><p>person的姓名是:{{ person.name }}, person的年龄是{{ person.age }}</p><p>user的用户名是:{{ user["username"] }}, user的邮箱是{{ user.email }}</p></body></html>

在这里插入图片描述
此外, 还可以通过对字典使用

**

运算,使字典变成关键字参数. 其效果与上面的代码等同.

@app.route('/variable')defvariable():
    hobby ="游戏"
    person ={"name":"张三","age":18}
    user = User("里斯","[email protected]")
    context ={'hobby': hobby,'person': person,'user': user
    }return render_template("variable.html",**context)

过滤器和测试器

用户自定义的过滤器

差点忘了Markdown是可以开二级标题的…
向html中传递参数时, 可能需要对传递的变量进行处理, 处理过后再显示, 如时间的格式化输出等, 此时可以用到过滤器. Jinjia2内置了许多过滤器, 但过滤器可以由用户进行自定义. 因为过滤器本质上是一个函数.
在定义了一个函数之后, 可以使用

app.add_template_filter(datetime_format, "dformat")

方法将函数添加为过滤器, 其中

datetime_format

为函数, 而

dformat

为过滤器名.

defdatetime_format(value,format="%Y-%d-%m %H: %M"):return value.strftime(format)

app.add_template_filter(datetime_format,"dformat")

除此之外, 还可以通过装饰器的方式定义过滤器.

@app.template_filter("dformat")defdatetime_format(value,format="%Y-%d-%m %H: %M"):return value.strftime(format)

可以看到, 使用的仍然是带参数的装饰器, 参数列表为过滤器的名称 ( 如果不加参数, 则默认将函数名当作过滤器的名称 ). 两种声明方法是等价的.

Jinjia2内置的过滤器

详情可查看官方文档.

测试器

用来测试某些元素是否满足条件, 如测试一个变量是否为字符串, 测试一个变量能否被调用(类似于

iscallable()

)等.

{% if user is defined %}
    user定义了:{{ user }}
{% else %}
    user没用定义。
{% endif %}

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

控制语句

if判断语句

Jinjia2中的if判断句与python中的if判断句非常相似, 甚至比较运算符和逻辑运算符都完全相同, 并且也使用elif作为else if. 注意, 当if语句块结束时, 需要声明

endif

.

{% if age > 18 %}
    <div>您已成年!</div>
{% elif age < 18 %}
    <div>您未成年!</div>
{% else %}
    <div>您刚成年!</div>
{% endif %}

👆Jinjia2中代码缩进的目的是更加方便阅读, 实际上任何代码缩进在Jinjia2中都是不必要的.
在这里插入图片描述

for循环语句

Jinjia2的for循环语句只是比python多加了一个

endfor

声明.

@app.route('/for')deffor_statement():
    books =[{"name":"三国演义","author":"罗贯中","price":100},{"name":"水浒传","author":"施耐庵","price":101},{"name":"西游记","author":"吴承恩","price":99},{"name":"红楼梦","author":"曹雪芹","price":88},]return render_template("for.html",books=books)
<!DOCTYPEhtml><htmllang="en"><head><metacharset="UTF-8"><title>for循环</title></head><body><table><thead><tr><th>书名</th><th>作者</th><th>价格</th></tr></thead><tbody>
            {% for book in books %}
                <tr><td>{{ book.name }}</td><td>{{ book.author }}</td><td>{{ book.price }}</td></tr>
            {% else %}
                <tr><tdcolspan="3"style="text-align: center;">无数据</td></tr>
            {% endfor %}
        </tbody></table></body></html>

👆如果被循环的列表books中没有元素, 那么可以定义else语句块, 显示"无数据".
在这里插入图片描述
在这里插入图片描述
此外, Jinjia2的for循环中还内置了许多有用的变量, 如获取当前循环到了第几次, 可以使用

loop.index

来查看.

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

👆添加loop.index
在这里插入图片描述
在这里插入图片描述在这里插入图片描述

模板结构

宏和import语句

模板中的宏(macro)与python中的函数非常相似, 可以传递参数但是没有返回值. 可以将一些常用的代码片段放到宏中, 然后把一些不固定的值抽取出来当成一个参数.
👇将宏定义在一个单独的文件forms.html中.

<!DOCTYPEhtml><htmllang="en"><head><metacharset="UTF-8"><title>forms</title></head><body>
{% macro input(name, value='', type='text') %}
    <inputtype="{{ type }}"value="{{ value|escape }}"name="{{ name }}">
{% endmacro %}
{% macro textarea(name, value='', rows=10, cols=40) %}
    <textareaname="{{ name }}"rows="{{ rows }}"cols="{{ cols }}">{{ value|escape }}</textarea>
{% endmacro %}
</body></html>

👆可以看到, 通过macro标签创建了一个名为input的宏, 它接收参数name和type.
👇导入宏, 使用import, 规则和python的import相同(支持import…as…和from…import…as…等语法). 加上with context, 可以导入当前模板中的变量.

<!DOCTYPE html><html lang="en"><head><meta charset="UTF-8"><title>变量使用</title></head><body><h1>我的兴趣爱好是:{{ hobby }}</h1><p>person的姓名是:{{ person.name }}, person的年龄是{{ person.age }}</p><p>user的用户名是:{{ user["username"]}}, user的邮箱是{{ user.email }}</p><p>{%if user is defined %}
            user定义了:{{ user }}{%else%}
            user没用定义。
        {% endif %}</p>{%import'forms.html'as forms with context %}<dl><dt>Username</dt><dd>{{ forms.input('username')}}</dd><dt>Password</dt><dd>{{ forms.input('password',type='password')}}</dd></dl><p>{{ forms.textarea('comment')}}</p></body></html>

在这里插入图片描述

模板继承

通过模板继承, 把一些重复性的代码写在父模板当中, 子模板继承父模板后, 再分别实现自己的代码.
在这里插入图片描述

模板环境

模板上下文

Jinjia2中的模板上下文即为在整个模板中都可以使用的变量, 可以通过

app.context_processor

进行声明. 此外, 还可以通过set方法进行创建. 使用set方法后, 创建的变量在这一句之后都是有效的.

{% set name = 'admin' %}

如果不想让这个变量污染全局环境, 还可以用with语句块指定作用域.

{% with %}
    {% set foo = 42 %}
    {{ foo }}
{% end with %}

也可以直接在with语句块内声明该作用域的变量:

{% with foo = 42 %}
    {{foo}}
{% end with %}

👆以上两种方式等价.
此外, Jinjia2中还有内置的全局变量, 如g, request, session和config.
Jinjia2虽然内置了一些全局变量, 但有时候仍然需要传递自定义的变量, 如很多网站的导航条右上角会显示当前登录的用户名, 这需要把

username

传递到几乎所有的模板, 定义一个全局变量很合适. 仍然是使用装饰器.

@app.context_processordefcontext_user():
    user ={"username":"admin","level":2}return{"user":user}

👆在自定义的上下文处理器函数中, 需要把变量放到字典中才能被函数所使用, 正如上述代码块所定义的.

全局函数

  • Jinjia2内置的全局函数有range, lipsum, dict等, 详情请查看Jinjia2的官方文档. 此外, 除了Jinjia2内置的全局函数, Flask也提供两个全局函数, 如之前使用过的url_for( 用于加载静态文件, 或者用于构建URL )以get_flashed_message( 用于获取闪现消息 ).
  • 自定义全局函数: 通过装饰器@app.template_global()
@app.template_global()defgreet(name):return"欢迎! %s"% name

使用:<div>{{ greet("詹森")}}</div>

闪现消息

使用闪现消息, 需要在视图函数中通过

flash()

提交要传递的消息, 然后再在模板中使用

get_flashed_messages

函数获取视图函数中的消息内容. 由于

get_flashed_messages

返回一个列表, 因此需要通过下标或者for循环来读取闪现消息.
Noteworthy的是, 闪现消息存储在session中, 使用session之前需要在app.config中设置SECRET_KEY, 幸运的是SECRET_KEY可以设置为任意字符串.

app.config['SECRET_KEY']="ewgnlew&S;12zd-+"@app.route('/flash')defmyflash():
    flash("闪现消息1...")
    flash("闪现消息2...")return render_template("flash.html")
<!DOCTYPEhtml><htmllang="en"><head><metacharset="UTF-8"><title>flash</title></head><body><ul>
    {% for message in get_flashed_messages() %}
        <li>{{ message }}</li>
    {% endfor %}
</ul></body></html>

在这里插入图片描述

标签: flask 前端 python

本文转载自: https://blog.csdn.net/fatfairyyy/article/details/126812605
版权归原作者 perSistence92 所有, 如有侵权,请联系我们删除。

“Flask Web——Jinjia2模板的使用”的评论:

还没有评论