模板

Flask 学习笔记

一、模板介绍


        模板是一个 web 开发必备的模块。因为我们在渲染一个网页的时候,并不是只渲染一个纯文本字符串,而是需要渲染一个有富文本标签的页面。这时候我们就需要使用模板了。在 Flask 中, 配套的模板是 Jinja2Jinja2 的作者也是 Flask 的作者。这个模板非常的强大,并且执行效率高。


1.1、Flask 渲染 Jinja 模板

在 flask 中可以直接以字符串的形式返回实现前端代码的效果,但这么做显然不太可能在工作中使用。

	from flask import Flask
	
	app = Flask(__name__)
	
	
	@app.route("/")
	def index():
	    return '<input type="text" class="s_ipt" name="wd" id="kw" maxlength="100" autocomplete="off">'
	
	
	if __name__ == '__main__':
	    app.run(debug=True)

渲染模块,说白了就是在 py 文件导入前端代码文件 html 进行使用,同时 py 文件也可以向 html 文件传递数据。通过 render_template() 方法即可实现。

值得注意的是,Flask() 方法设置 render_template() 默认访问的是当前文件夹下的 templates 文件夹(创建 flask 项目会自动创建),所有的前端文件都应放在这。当然也可以通过 template_folder 参数修改(但比建议修改)。

	<!DOCTYPE html>
	<html lang="en">
	<head>
	    <meta charset="UTF-8">
	    <title>Title</title>
	</head>
	<body>
	    <input type="text" class="s_ipt" name="wd" id="kw" maxlength="100" autocomplete="off">
	</body>
	</html>
	from flask import Flask, render_template
	
	# 绝对路径 相对路径都可以
	app = Flask(__name__, template_folder=r"./demo")
	
	
	@app.route("/")
	def index():
	    return render_template("index.html")
	
	
	if __name__ == '__main__':
	    app.run(debug=True)



1.2、传参数

  1. 直接传
	@app.route("/")
	def index():
	    # 直接传
	    return render_template("index.html", name="直接传", age=18)
	<!-- 在html文件使用 {{}} 接收 -->
	<h2>{{name}}</h2>
	<h2>{{age}}</h2>

  1. 使用字典传
	@app.route("/")
	def index():
	    dic = {
	        "name": "用户名",
	        "password": "密码"
	    }
	return render_template("index.html", context=dic)
    <h2>{{context}}</h2>
    <h2>{{context.name}}</h2>

  1. 使用 ** 字典
	@app.route("/")
	def index():
		# 使用 ** 可以把 "name": "用户名" 转为 "name"="用户名"
	    dic = {
	        "name": "用户名",
	        "password": "密码",
	        "books": {
	            "Python": 56,
	            "Java": 55
	        },
	        "lis": [1, 2, 3]
	    }
	return render_template("index.html", **dic)
    <h2>{{name}}</h2>
    <h2>{{password}}</h2>
    <!-- 可用 "." , 也可用 "索引" 访问 -->
    <h2>{{books.Python}}</h2>
    <h2>{{books["Java"]}}</h2>
    <h2>{{lis.1}}</h2>
    <h2>{{lis[0]}}</h2>

  1. 再说过小 bug 吧

    在 flask 引用的 html 文件中进行代码注释不能用 <!-- -->,因为它仍会对其中的变量等进行索引,若变量不存在代码有错误它还是会报错。因此可以用 {# #},当然那些用于解释代码的注释是没什么影响的。
<!-- 在用 ** 引入的例子中,在 html 文件加入下面的注释代码仍会报错 -->
<!-- <h2>{{context}}</h2> #} -->

<!-- 改为下列就不会-->
{# <h2>{{context}}</h2> #}



二、Jinja2 模板过滤器


        过滤器是通过管道符号 | 在前端代码进行使用的,例如:{{ name|length }},将返回变量 name 的长度。过滤器相当于是一个函数,把当前的变量传入到过滤器中,然后过滤器根据自己的功能,再返回相应的值,之后再将结果渲染到页面中。Jinja2 中内置了许多过滤器,在这里可以看到所有的过滤器。

2.1、内置的过滤器

  1. abs(value):返回一个数值的绝对值。

  2. length(value):返回一个序列或者字典的长度。

  3. default(value, default_value, boolean=false):如果当前变量没有值,则会使用参数中的值来代替。如果当前变量不存在(未创建),则会使用 default_value 来替代。boolean=False 默认是在只有这个变量未定义的时候才会使用 default 中的值,如果想使用 python 的形式判断是否为 false,则可以传递 boolean=true。

	@app.route("/")
	def index():
	    dic = {
	        "name": "  老王  ",
	        "num": -66,
	        "val": None
	    }
	    return render_template("index.html", **dic)
	<body>
	    <p>{{ name }}</p>
	    <p>{{ name|length }}</p>
	    <p>{{ num|abs }}</p>
	    <p>{{ val|default("默认值") }}</p>
	    <p>{{ acd|default("acd 变量不存在") }}</p>
	    <p>{{ val|default("Python 的形式判断是否为 false", boolean=true) }}</p>
	</body>
  1. escape(value)或e:转义字符,会将<、>等符号转义成 HTML 中的符号(在页面源代码中进行了转义)。

  2. safe(value):如果开启了全局转义,那么 safe 过滤器会将变量关掉转义。

  3. first(value):返回一个序列的第一个元素。

  4. last(value):返回一个序列的最后一个元素。

  5. join(value, d=u''):将一个序列用 d 这个参数的值拼接成字符串。

  6. format(value, *arags, **kwargs):格式化字符串。

	@app.route("/")
	def index():
	    dic = {
	        "name": "  老王  ",
	        "num": -66,
	        "val": None,
	        "h1": "<h1>你好   li</h1>",
	        "books": ['Python', 'Java', 'PHP']
	    }
	    return render_template("index.html", **dic)
    <p>{{ h1|escape }}</p>
    <!-- 似乎不用 escape 也可以自动转换 -->
    <p>{{ h1 }}</p>
    
    <!-- 关闭自动转义 -->
    {% autoescape off %}
    <p>{{ h1 }}</p>
    {% endautoescape %}
    
    <!-- 也可以使用 safe 使其变为安全变量, 达到关闭自动转义的效果 -->
    <p>{{ h1|safe }}</p>

    <p>{{ books|first }}</p>
    <p>{{ books|last }}</p>
    <p>{{ books|length }}</p>
    <!-- 若是合乎逻辑的话, 也可以联用 -->
    <p>{{ books|first|length }}</p>
    <p>{{ books|first|last }}</p>
    
    <p>{{ books|join(d='-') }}</p>
    <p>{{ "%s - %s"|format(h1, name) }}</p>
  1. int(value):将值转换为 int 类型。

  2. float(value):将值转换为 float 类型。

  3. string(value):将变量转换成字符串。

  4. lower(value):将字符串转换为小写。

  5. upper(value):将字符串转换为大写。

  6. replace(value, old, new): 替换将 old 替换为 new 的字符串。

  7. truncate(value, length=255, killwords=False):截取 length 长度的字符串。常用于文章标题的显示,太长在网页中不能完全显示,所以后面的内容用 ... 代替,因此 length 的值不能小于 3,显示的文字 = length - 3

  8. striptags(value):删除字符串中所有的 HTML 标签,如果出现多个空格,将替换成一个空格。

  9. trim(value):截取字符串前面和后面的空白字符。

  10. wordcount(value):计算一个长字符串中单词的个数(以空格为分隔,并不是严格的按单词分)。

	@app.route("/")
	def index():
	    dic = {
	        "name": "  老王  ",
	        "num": -66,
	        "val": None,
	        "h1": "<h1>你好   li</h1>",
	        "books": ['Python', 'Java', 'PHP'],
	        "user": "Cool",
	        "wc": "hello llo i"
	    }
	    return render_template("index.html", **dic)
    <p>{{ num|int }}</p>
    <p>{{ num|float }}</p>
    <p>{{ num|string }}</p>
    <p>{{ user|lower }}</p>
    <p>{{ user|upper }}</p>
    <p>{{ user|replace("o", "88") }}</p>
    <p>{{ wc|truncate(length=4) }}</p>
    <p>{{ h1|striptags }}</p>
    <p>截取前的长度:{{ name|length }}</p>
    <p>截取后的长度:{{ name|trim|length }}</p>
    <p>{{ wc|wordcount }}</p>



2.2、自定义过滤器

  1. 定义一个简单的过滤器
	@app.template_filter("my_cut")
	def cut(value):
	    '''
	    把 hello 替换成 你好
	    :param value:
	    :return:
	    '''
	    return value.replace("hello", "你好")
 	<p>{{ wc|my_cut }}</p>

  1. 定义一个显示时间的过滤器
	@app.route("/")
	def index():
	    dic = {
	        # datetime(年, 月, 日, 时, 分, 秒)
	        "now_time1": datetime(2020, 4, 16, 14, 15, 0),
	        "now_time2": datetime(2020, 4, 16, 14, 0, 0),
	        "now_time3": datetime(2020, 4, 16, 10, 0, 0)
	    }
	    return render_template("index.html", **dic)
	
	
	from datetime import datetime
	
	@app.template_filter("handle_time")
	def handle_time(time):
	    '''
	    小于1分钟  =>  刚刚
	    大于1分钟 小于1小时  =>  xx 分钟之前
	    大于1小时 小于24小时  =>  xx 小时之前
	    :param time:
	    :return:
	    '''
	
	    # 先判断传入的参数是不是 时间戳
	    if isinstance(time, datetime):
	        now = datetime.now()
	        # total_seconds() 得到具体的秒数
	        timestamp = (now - time).total_seconds()
	
	        if (timestamp < 60):
	            return "刚刚"
	        elif (timestamp < 60*60):
	            return f"{int(timestamp/60)} 分钟之前"
	        elif (timestamp < 60*60*24):
	            return f"{int(timestamp/60/60)} 小时之前"
	    else:
	        return time
	
	
	if __name__ == '__main__':
	    app.run(debug=True)
    <p>{{ now_time1|handle_time}}</p>
    <p>{{ now_time2|handle_time}}</p>
    <p>{{ now_time3|handle_time}}</p>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值