02-模板(过滤器,控制代码块)

学习目标

  • 能够写出 jinja2 中变量代码块和控制代码块的格式
  • 能够写出在模板中字典,列表的取值方式
  • 能够写出数组反转的自定义过滤器(使用1种方式即可)
  • 能够说出Flask中模板代码复用的三种方式
  • 能够使用代码实现模板继承的功能
  • 能够说出可以在模板中直接使用的 Flask 变量和函数
  • 能够使用 Flask-WTF 扩展实现注册表单
  • 能够说出 CSRF 攻击的原理

Jinja2模板引擎简介

模板

  在前面的示例中,视图函数的主要作用是生成请求的响应,这是最简单的请求。实际上,视图函数有两个作用:处理业务逻辑和返回响应内容。在大型应用中,把业务逻辑和表现内容放在一起,会增加代码的复杂度和维护成本。本节学到的模板,它的作用即是承担视图函数的另一个作用,即返回响应内容。

  • 模板其实是一个包含响应文本的文件,其中用占位符(变量)表示动态部分,告诉模板引擎其具体的值需要从使用的数据中获取
  • 使用真实值替换变量,再返回最终得到的字符串,这个过程称为“渲染”
  • Flask是使用 Jinja2 这个模板引擎来渲染模板

使用模板的好处:

  • 视图函数只负责业务逻辑和数据处理(业务逻辑方面)
  • 而模板则取到视图函数的数据结果进行展示(视图展示方面)
  • 代码结构清晰,耦合度低

  

Jinja2:

  Jinja2:是Python下一个被广泛应用的模板引擎,是由Python实现的模板语言,他的设计思想来源于Django的模板引擎,并扩展了其语法和一系列强大的功能,他是Flask内置的模板语言。

  模板语言:是一种被设计来自动生成文档的简单文本格式,在模板语言中,一般都会把一些变量传给模板,替换模板的特定位置上预先定义好的占位变量名。

渲染模板函数

  Flask提供的render_template函数封装了该模板引擎,render_template函数的第一个参数是模板的文件名,后面的参数都是键值对,表示模板中变量对应的真实值。

使用

<h1>{{ post.title }}</h1>

{{}}来表示变量名,这种{{}}语法叫做变量代码块

Jinja2模板中的变量代码块可以是任一Python类型或者对象,只要他能够被Python的str()方法转换为一个字符串就可以,比如,可以通过下面的方法显示一个字典或者列表中的某个元素。

{{your_dict[‘key‘]}}
{{your_list[0]}}

用{%%}定义控制代码块,可以实现一些语言层次的功能比如循环或者if语句。

{% if user %}
    {{ user }}
{% else %}
    hello!
<ul>
    {% for index in indexs %}
    <li> {{ index }} </li>
    {% endfor %}
</ul>

注释

使用{# #}进行注释,注释的内容不会再html中渲染出来。

{# {{ name }} #}

模板的使用

  在项目下,创建temolates文件夹,用于存放所有的模板文件,并在目录下创建一个html文件,temp_demo1.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
我的模板html内容
</body>
</html>

设置templates文件夹属性以便能够在代码中有智能提示。

设置html中的模板语言,以便在html有智能提示。

创建视图函数,将模板内容进行渲染返回

from flask import Flask,render_template

app = Flask(__name__)

@app.route(‘/‘)
def hello_world():
    return render_template("temp_demo1.html")

if __name__ == ‘__main__‘:
    app.run()

代码中传入字符串,列表,字典到模板中

from flask import Flask,render_template

app = Flask(__name__)

@app.route(‘/‘)
def hello_world():
    #往模板中传入数据
    my_str = "hello lishuntao"
    my_int = 100
    my_arr = [1,4,6,7,8]
    my_dic = {
        "name":"lishuntao",
        "pwd":"123456",
    }
    #渲染模板
    return render_template("temp_demo1.html",my_str=my_str,
                           my_int=my_int,
                           my_arr=my_arr,
                           my_dic=my_dic)

if __name__ == ‘__main__‘:
    app.run(port=8005)

模板中的显示代码:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>模板</title>
</head>
<body>
{{ my_str }}
{{ my_int }}
{{ my_arr }}
{{ my_dic }}
</body>
</html>

相关运算,取值

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>模板</title>
</head>
<body>
<br/>{{ my_str }}
<br/>my_int + 10 的和为:{{ my_int + 10 }}
<br/>数组的第0个值+my_int:{{ my_arr[0]+my_int }}
<br/>数组的第0个值:{{ my_arr[0] }}
<br/>数组的第1个值:{{ my_arr.1 }}
<br/>my_dic中name值:{{ my_dic["name"] }}
<br/>my_dic中pwd值:{{ my_dic["pwd"] }}
</body>
</html>

过滤器

  过滤器的本质就是函数。有时候我们不仅仅只是需要输出变量的值,我们还需要修改变量的显示,甚至格式化、运算等等,而在模板中是不能直接调用 Python 中的某些方法,那么这就用到了过滤器。

使用方式:

#过滤器的使用方式为:变量名 | 过滤器。

{{variable | filter_name(*args)}}

如果没有任何参数传给过滤器,则可以把括号省略掉:

{{variable | filter_name}}

链式调用:(在Jinja2中,过滤器是可以支持链式调用的,示例如下:)

{{ "hello world" | reverse | upper }}

常见内建过滤器

字符串操作:

safe:禁用转义

<p>{{ ‘<em>hello</em>‘ | safe }}</p>

capitalize:把变量值的首字母转成大写,其余字母转小写

<p>{{ ‘hello‘ | capitalize }}</p>

lower:把值转小写

<p>{{ ‘HELLO‘ | lower }}</p>

upper:把值转成大写

<p>{{ ‘hello‘ | upper }}</p>

title:把值中的每个单词的首字母都转成大写

<p>{{ ‘hello‘ | title }}</p>

reverse:字符串反转

<p>{{ ‘olleh‘ | reverse }}</p>

format:格式化输出

<p>{{ ‘%s is %d‘ | format(‘name‘,17) }}</p>

striptags:渲染之前把值中所有的HTML标签都删掉

<p>{{ ‘<em>hello</em>‘ | striptags }}</p>

列表操作

first:取第一个元素

<p>{{ [1,2,3,4,5,6] | first }}</p>

last:取最后一个元素

<p>{{ [1,2,3,4,5,6] | last }}</p>

length:获取列表长度

<p>{{ [1,2,3,4,5,6] | length }}</p>

sum:列表求和

<p>{{ [1,2,3,4,5,6] | sum }}</p>

sort:列表排序

<p>{{ [6,2,3,1,5,4] | sort }}</p>

语句块过滤

{% filter upper %}
    #一大堆文字#
{% endfilter %}

自定义过滤器

过滤器的本质是函数。当模板内置的过滤器不能满足需求,可以自定义过滤器。自定义过滤器有两种实现方式:

  • 一种是通过Flask应用对象的 add_template_filter 方法
  • 通过装饰器来实现自定义过滤器

重要:自定义的过滤器名称如果和内置的过滤器重名,会覆盖内置的过滤器。

需求:添加列表反转的过滤器

方式一:

  通过调用应用程序实例的 add_template_filter 方法实现自定义过滤器。该方法第一个参数是函数名,第二个参数是自定义的过滤器名称:

#过滤器的本质势函数,那么写一个反转函数
def do_listreverse(li):
    # 通过原列表创建一个新列表(不改动原列表)
    temp_li = list(li)
    # 将新列表进行返转
    temp_li.reverse()
    #返回新列表
    return temp_li
#第一个参数是自己写的过滤器的函数,第二个是自己定义过滤器使用的名字
app.add_template_filter(do_listreverse,‘lireverse‘)

方式二:

用装饰器来实现自定义过滤器。装饰器传入的参数是自定义的过滤器的名称。

#用装饰器来自定义过滤器,参数是自定义过滤器名称
@app.template_filter(‘lireverse‘)
def do_listreverse(li):
    # 通过原列表创建一个新列表
    temp_li = list(li)
    # 将新列表进行返转
    temp_li.reverse()
    return temp_li

在html中使用该自定义过滤器:

<br/> my_arr 原内容:{{ my_arr }}
<br/> my_arr 反转:{{ my_arr | lireverse }}

控制代码块

主要有两个:

1 if/else if /else / endif
2 for / endfor

if语句

Jinja2 语法中的if语句跟 Python 中的 if 语句相似,后面的布尔值或返回布尔值的表达式将决定代码中的哪个流程会被执行:

{%if user.is_logged_in() %}
    <a href=‘/logout‘>Logout</a>
{% else %}
    <a href=‘/login‘>Login</a>
{% endif %}

过滤器还可以用在if语句中

{% if comments | length > 0 %}
    There are {{ comments | length }} comments
{% else %}
    There are no comments
{% endif %}

循环

我们可以在Jinja2中使用循环来迭代任何列表或者生成器函数

{% for post in posts %}
    <div>
        <h1>{{ post.title }}</h1>
        <p>{{ post.text | safe }}</p>
    </div>
{% endfor %}

  循环和if语句可以组合使用,以模拟 Python 循环中的 continue 功能,下面这个循环将只会渲染post.text不为None的那些post:

{% for post in posts if post.text %}
    <div>
        <h1>{{ post.title }}</h1>
        <p>{{ post.text | safe }}</p>
    </div>
{% endfor %}

在一个 for 循环块中你可以访问这些特殊的变量:

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

在循环内部,你可以使用一个叫做loop的特殊变量来获得关于for循环的一些信息

  • 比如:要是我们想知道当前被迭代的元素序号,并模拟Python中的enumerate函数做的事情,则可以使用loop变量的index属性,例如:
{% for post in posts%}
{{loop.index}}, {{post.title}}
{% endfor %}

cycle函数会在每次循环的时候,返回其参数中的下一个元素,可以拿上面的例子来说明:

{% for post in posts%}
{{loop.cycle(‘odd‘,‘even‘)}} {{post.title}}
{% endfor %}

输出结果:

odd Post Title
even Second Post

示例程序:

app.py:

from flask import Flask,render_template

app = Flask(__name__)

@app.route(‘/‘)
def hello_world():
    my_list = [
        {
            "id": 1,
            "value": "我爱工作"
        },
        {
            "id": 2,
            "value": "工作使人快乐"
        },
        {
            "id": 3,
            "value": "沉迷于工作无法自拔"
        },
        {
            "id": 4,
            "value": "日渐消瘦"
        },
        {
            "id": 5,
            "value": "爱学习,爱自己"
        }
    ]
    #渲染模板
    return render_template("temp_demo1.html",my_list=my_list,
                          )

if __name__ == ‘__main__‘:
    app.run(port=8005,debug=True)

模板代码:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>模板</title>
</head>
<body>
{# 只显示4行数据,背景颜色依次为:黄,绿,红,紫,总共是五行数据 #}
{% for item in my_list if item.id != 5 %}
    {% if loop.index == 1 %}
        <li style="background-color: orange">{{ item.value }}</li>
    {% elif loop.index == 2 %}
        <li style="background-color: green">{{ item.value }}</li>
    {% elif loop.index == 3 %}
        <li style="background-color: red">{{ item.value }}</li>
    {% else %}
        <li style="background-color: purple">{{ item.value }}</li>
    {% endif %}
{% endfor %}
</body>
</html>

原文地址:https://www.cnblogs.com/lishuntao/p/11687556.html

时间: 2024-10-05 05:32:00

02-模板(过滤器,控制代码块)的相关文章

常用代码块模板,get,load区别,session.get(,)参数解释,session方法总结

设置模板代码步骤:window->java->Templates->new模板代码Session session = HibernateUtils.openSession(); try { HibernateUtils.startTransaction(); /** * 具体的业务代码 */ HibernateUtils.commitTransaction(); } catch (Exception e) { HibernateUtils.rollBackTransaction(); t

Scala基础篇-02函数与代码块

1.block 代码块也是表达式,其最终求得的值是最后一个表达式的值. {exp1;exp2} { exp1 exp2 } 2.function def funtionName(param:ParamType):ReturnType{ //function body: expressions } 3.例子 利用字符串插值特性:s"...${...}..." 省略花括号: 原文地址:https://www.cnblogs.com/moonlightml/p/9864560.html

Django——模板层(template)(模板语法、自定义模板过滤器及标签、模板继承)

阅读目录(Content) 模板语法之变量 模板之过滤器 default length filesizeformat date slice truncatechars safe 模板之标签 自定义标签和过滤器 模板继承 (extend) 模板语法之include 前言:当我们想在页面上给客户端返回一个当前时间,一些初学者可能会很自然的想到用占位符,字符串拼接来达到我们想要的效果,但是这样做会有一个问题,HTML被直接硬编码在 Python代码之中. 1 2 3 4 def current_dat

django模板&amp;过滤器

django模板&过滤器 声明:部分信息来源这篇博客https://www.cnblogs.com/maple-shaw/articles/9333821.html MVC: 模型(model)-------->模型 视图(view)----->html 控制器(controller)--------->业务逻辑 Django框架的设计模式借鉴了MVC框架的思想,也是分成三部分,来降低各个部分之间的耦合性. Django框架的不同之处在于它拆分的三部分为:Model(模型).Te

10_jinja2模板过滤器

目录 Jinja2模板过滤器 常用过滤器 列表操作 Jinja2模板过滤器 常用过滤器 default: 有则使用传的,没则使用默认值 使用方式: {{ value|default('默认值') }}, 如果value这个key不存在,则会使用default过滤器提供的默认值.如果你想使用类似于python中判断一个值是否为False (例如:None, 空字符串,空列表,空字典等), 那么就必须要传递另外一个参数{{ value|default('默认值', boolean=True) }},

Java误区: 静态代码块,当把类将被载入到自己主动运行?

JAVA静态代码块会在类被载入时自己主动运行? 非常多Java开发人员的思想,被这个思想深深的轮奸了n遍,传播这个错误思想的博客,在网上一堆,越来越多的人被轮奸. 如:http://blog.csdn.net/leeyu35/article/details/7755304 那么我们程序来证明这句话是错误的: class MyClass1 { static {//静态块 System.out.println("static block "); } } public class Main

xCode中如何保存自己的代码块

在开发iOS的过程中,xCode肯定是用得最多的工具,没有之一.因为苹果官方提供的就这一个平台,虽然没有竞争对手,但秉承苹果一贯的注重细节的原则,xCode还是一款相当不错的IDE. 作为一名iOS开发攻城狮,你肯定需要记住苹果一大堆的API,数量之多足够让你崩溃.而且现在的API的趋势也是越来越长,不再纠结于尽量短小精悍了.那么问题来了,虽然有代码补全提示,但你至少要记得开头的几个字母吧?你有没有脑子一片空白,基本啥都不记得的情况了? 比如说我要访问Bundle下的readme.txt文件,那

ASP.NET 网页中的嵌入式代码块

将代码添加到 ASP.NET 网页中的默认模型要么创建一个代码隐藏类文件(代码隐藏页),要么将页的代码写到具有 runat="server" 特性的 script 块中(单文件页). 编写的代码通常会与页上的控件进行交互. 例如,通过从代码中设置控件的 Text(或其他)属性,可以在页上显示信息. 另一种可能是使用嵌入式代码块将代码直接嵌入到页中. 嵌入式代码块 嵌入式代码块是在呈现页面的过程中执行的服务器代码. 块中的代码可以执行编程语句,并调用当前页类中的函数. 下面的代码示例演示

Oracle实践--PL/SQL基础之代码块

PL/SQL基础入门之代码块 PL/SQL:过程语言(Procedure  Language)和结构化语言(Structured Query Language)结合而成的编程语言,是对SQL的扩展,支持多种数据类型,如大对象和集合类型,可使用条件和循环等控制语句,可创建存储过程,程序包和触发器等,给sql语句的执行添加程序逻辑,与Oracle服务器和Oracle工具紧密集成,具有可移植性,灵活性和安全性. 优点: 1.       支持SQL,可以使用:DML,DCL,游标控制和SQL运算符 2