flask框架之jinjia2模版语法详解

前言

这几年一直在it行业里摸爬滚打,一路走来,不少总结了一些python行业里的高频面试,看到大部分初入行的新鲜血液,还在为各样的面试题答案或收录有各种困难问题

于是乎,我自己开发了一款面试宝典,希望能帮到大家,也希望有更多的Python新人真正加入从事到这个行业里,让python火不只是停留在广告上。

微信小程序搜索:Python面试宝典

或可关注原创个人博客:https://lienze.tech

也可关注微信公众号,不定时发送各类有趣猎奇的技术文章:Python编程学习

JinJa2模版语法

Jinja 2 默认配置如下:

  • 所有扩展名为 .html.htm.xml 以及 .xhtml 的模板会开启自动转义
  • 模板可以利用 {% autoescape %} 标签选择自动转义的开关。
  • Flask 在 Jinja2 上下文中插入了几个全局函数和助手,另外还有一些目前默认的值

于django的模版语言template类似,但是更强大,还可以支持函数传递,模版中的函数调用,并且传递参数等

...
return render_template("index.html", double=lambda x : x * 2)
{{ double(2) }}
{{ (".").join(["a","b","c"]) }}

模版变量

{{}}: 来表示变量名


Jinja2 模版中的变量代码块可以是任意 Python 类型或者对象,只要它能够被 Python 的 str() 方法转换为一个字符串就可以

比如,可以通过下面的方式显示一个字典或者列表中的某个元素

{{ object['key'] }}
{{ object.key }}
{{ object[0] }}

模版控制

{% %}: 定义的控制代码块,可以实现一些语言层次的功能,比如循环或者if语句,类似django的模版语言哦


{% if 条件1 %}
	语句块1
{% elif 条件2 %}
	语句块2
{% else %}
	不符合所有条件
{% endif %}
{% for index in indexs if index!=1 %}
	<li> {{ index }} </li>
{% endfor %}

过滤器

过滤器的本质就是函数。有时候我们不仅仅只是需要输出变量的值,我们还需要修改变量的显示,甚至格式化、运算等等,那么这就用到了过滤器

{{ object | filter}}

  • 字符串过滤器
过滤器说明
safe禁止转义,渲染时不会转义特殊字符
capitallize把首字母转大写,其他的字母转小写
lower把所有的字母转小写
upper把所有字母转大写
title把每个单词的首字母转大写
trim去掉首尾空格
striptags去掉所有的HTML标签
join将多个值拼接成字符串,类似python的join()函数
replace替换字符串的值
round对数字四舍五入
int转换成int类型

  • 列表过滤器
过滤器说明
first获取列表的第一个元素
last获取列表的最后一个
sort排序列表
sum列表求和
length列表的长度

模版上下文

下面的全局变量默认在 Jinja2 模板中可用:

  • config

    当前的配置对象 (flask.config)0.6 新版功能.在 0.10 版更改: 现在这总是可用的,甚至在导入的模版里。

  • request

    当前的请求对象 (flask.request)。当模版不是在活动的请求上下文中渲染时这个变量不可用。

  • session

    当前的会话对象 (flask.session)。当模版不是在活动的请求上下文中渲染时这个变量不可用。

  • g

    请求相关的全局变量 (flask.g)。当模版不是在活动的请求上下文中渲染时这个变量不可用。

  • url_for()

    flask.url_for() 函数

  • get_flashed_messages()

    flask.get_flashed_messages() 函数

自动转义

自动转义的概念是自动转义特殊字符。 HTML (或 XML ,因此也有 XHTML )意义下的特殊字符是 &><" 以及 '

因为这些字符在文档中表示它们特定的含义,如果你想在文本中使用它们,应该把它们替换成相应的“实体”。不这么做不仅会导致用户疲于在文本中使用这些字符,也会导致安全问题。 (见 跨站脚本攻击(XSS)

虽然你有时会需要在模板中禁用自动转义,比如在页面中显式地插入 HTML , 可以是一个来自于 markdown 到 HTML 转换器的安全输出

我们有三种可行的解决方案:

  • 在传递到模板之前,用 Markup 对象封装 HTML字符串。一般推荐这个方法
  • 在模板中,使用 |safe 过滤器显式地标记一个字符串为安全的 HTML ( {{ myvariable|safe }}
  • 临时地完全禁用自动转义系统

在模板中禁用自动转义系统,可以使用 {%autoescape %}

{% autoescape false %}
    <p>autoescaping is disabled here
    <p>{{ will_not_be_escaped }}
{% endautoescape %

自定义过滤器

如果你要在 Jinja2 中注册你自己的过滤器,你有两种方法。你可以把它们手动添加到应用的 jinja_env 或者使用 template_filter() 装饰器。

下面两个例子作用相同,都是反转一个对象

@app.template_filter('reverse')
def reverse_filter(s):
    return s[::-1]

def reverse_filter(s):
    return s[::-1]
app.jinja_env.filters['reverse'] = reverse_filter

在使用装饰器的情况下,如果你想以函数名作为过滤器名,参数是可选的。

注册之后, 你可以在模板中像使用 Jinja2 内置过滤器一样使用你的过滤器,例如你在上下文中有一个名为 mylist 的 Python 列表

{% for x in mylist | reverse %}
{% endfor %}

模版函数

如果你希望在模版中,可以使用一些常用的方法,但是为了不在每个视图都定义一次,那么可以使用template_global将函数注册为模板全局函数

这样在每个模版里都可以很快乐的随意使用了

@app.template_global()
def length(s):
    return len(str(s))

使用还是老样子

{{ length("abc") }}

模版静态加载

如果希望在模版中加载静态资源,无非两种办法,第一种是使用相对路径

<link href="../static/bootstrap.css" rel="stylesheet">

第二种是动态获取路径,使用模版提供的url_for方法反向解析到static目录

{{ url_for("static", filename="bootstrap.css") }}

JinJa2模版重用

模版宏

宏类似于Python中的函数,宏的作用就是在模板中重复利用代码,避免代码冗余

Jinja2支持宏,还可以导入宏,需要在多处重复使用的模板代码片段可以写入单独的文件,再包含在所有模板中,以避免重复


  • {% macro %}: 定义个宏
{% macro macro_test(href) %}
	<h3>这是个宏</h3>
	<a href="{{ href }}">这是链接</a>
{% endmacro %}
  • 使用宏
{{ macro_test("https://baidu.com") }}

宏一般会定义为一个html文件,在其他模版中可以导入使用

  • 定义一个测试宏文件macro_input.html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
{% macro user_form(username,password) %}
    <input type="text" name="username" value="{{ username }}">
    <input type="password" name="password" value="{{ password }}">
    <input type="submit" value="submit">
{% endmacro %}
</body>
</html>
  • 使用这个宏文件
{% import 'macro_input.html' as macro_input %}
{{ macro_input.user_form("admin","123456") }}

模版继承

模板继承是为了重用模板中的公共内容

一般Web开发中,继承主要使用在网站的顶部菜单、底部。这些内容可以定义在父模板中,子模板直接继承,而不需要重复书写


{% block %}标签定义的内容,相当于在父模板中挖个坑,当子模板继承父模板时,可以进行填充

  • 父模版
{% block top %}
	顶部菜单 导入一系列css样式等
{% endblock top %}

{% block content %}
	内容
{% endblock content %}

{% block bottom %}
	底部 导入一系列js等
{% endblock bottom %}
  • 子模版,使用{% extends %}标签引入父模版
{% extends 'base.html' %}
{% block content %}
	需要填充的内容
{% endblock content %}

  • 注意
    • 不支持多继承
    • 为了便于阅读,在子模板中使用extends时,尽量写在模板的第一行
    • 不能在一个模板文件中定义多个相同名字的block标签
    • 当在页面中使用多个block标签时,建议给结束标签起个名字,当多个block嵌套时,阅读性更好

模版包含

Jinja2模板中,除了宏和继承,还支持一种代码重用的功能,叫包含{% include %}

它的功能是将另一个模板整个加载到当前模板中,并直接渲染


包含在使用时,如果包含的模板文件不存在时,程序会抛出TemplateNotFound异常,可以加上ignore missing关键字

如果包含的模板文件不存在,会忽略这条include语句

{% include 'index.html' ignore missing %}

宏(Macro)、继承(Block)、包含(include)均能实现代码的复用。

继承(Block)的本质是代码替换,一般用来实现多个页面中重复不变的区域。

宏(Macro)的功能类似函数,可以传入参数,需要定义、调用。

包含(include)是直接将目标模板文件整个渲染出来。

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

李恩泽的技术博客

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值