1、模板文件的自动更新

  1. from flask import Flask
  2. app = Flask(__name__)
  3. app.config["TEMPLATES_AUTO_RELOAD"] = True # 实现模板文件修改后,python文件中能够自动更新
  4. # app.config.updata("TEMPLATES_AUTO_RELOAD"=True)

2、模板过滤器

定义:过滤器是通过管道符号shift+\(|)进行使用的,例如:{{ name(参数) | length(函数) }},将返回name的长度。过滤器相当于是一个函数,把当前的变量传入到过滤器中,然后过滤器根据自己的功能,再返回相应的值,之后再将结果渲染到页面中。Jinja2中内置了许多过滤器:(过滤器只能在模板中使用,而不能在python文件中使用)
• abs(value):返回一个数值的绝对值。

• default(value,default_value,boolean=false):如果当前变量没有值,则会使用参数中的值来代替。name|default(‘juran’)——如果name不存在,则会使用juran来替代。boolean=False默认是在只有这个变量为undefined的时候才会使用default中的值,如果想使用python的形式判断是否为false,则可以传递boolean=true。也可以使用or来替换。

• escape(value)或e:转义字符,会将<、>等符号转义成HTML中的符号。例如:content|escape或content|e。

• first(value):返回一个序列的第一个元素。names|first。

• format(value,*arags,kwargs):格式化字符串。例如以下代码:
{{ “%s” - “%s”|format(‘Hello?’,”Foo!”) }}将输出:Helloo? - Foo!
注意是横线(-)进行连接**

• last(value):返回一个序列的最后一个元素。示例:names|last。

• length(value):返回一个序列或者字典的长度。示例:names|length。

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

• safe(value):如果开启了全局转义,那么safe过滤器会将变量关掉转义。示例:content_html|safe。

• int(value):将值转换为int类型。

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

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

• upper(value):将字符串转换为小写。

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

• truncate(value,length=255,killwords=False):截取length长度的字符串。

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

• trim:截取字符串前面和后面的空白字符。

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

• wordcount(s):计算一个长字符串中单词的个数。

1、示例:default过滤器
代码部分:(tel参数没有被定义)

  1. from flask import Flask, render_template
  2. app = Flask(__name__)
  3. @app.route("/")
  4. def home():
  5. return "首页"
  6. # 改字典中不添加tel参数
  7. dic = {
  8. "name":"流浪者、j",
  9. "home":"兰溪",
  10. "age":18
  11. }
  12. @app.route("/index/")
  13. def index():
  14. return render_template("index.html", **dic)
  15. if __name__ == "__main__":
  16. # app.config.from_pyfile('settings.py',silent=True)
  17. app.run(debug=True)

模板部分:

  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="UTF-8">
  5. <title>Title</title>
  6. </head>
  7. <body>
  8. <input type="text" class="query" id="upquery" name="query" maxlength="100" len="80" onfocus="focusInput(this)" ov="汇拼" value="汇拼" autocomplete="off">
  9. <h1>{{ name }}</h1>
  10. <h1>{{ home }}</h1>
  11. <h2>{{ age }}</h2>
  12. <!-- 传入并不存在的参数tel -->
  13. <h2>{{ tel|default('这个人的性别是一个秘密') }}</h2>
  14. </body>
  15. </html>

网页显示:(显示在default函数中添加的部分)
image.png

代码部分:如果在代码部分存在参数那么就显示该参数对应的值,无论该参数对应的是什么(空、None)都会在网页中体现**

  1. from flask import Flask, render_template
  2. app = Flask(__name__)
  3. @app.route("/")
  4. def home():
  5. return "首页"
  6. dic = {
  7. "name":"流浪者、j",
  8. "home":"兰溪",
  9. "age":18
  10. "tel":None
  11. }
  12. @app.route("/index/")
  13. def index():
  14. return render_template("index.html", **dic)
  15. if __name__ == "__main__":
  16. # app.config.from_pyfile('settings.py',silent=True)
  17. app.run(debug=True)

模板部分不变
网页显示:(显示自己定义的参数值)
image.png

2、模板转义机制的说明与解决
代码部分:定义一个代码**

  1. from flask import Flask, render_template
  2. app = Flask(__name__)
  3. @app.route("/")
  4. def home():
  5. return "首页"
  6. dic = {
  7. "es":"<script>alert('hello');</script>"
  8. }
  9. @app.route("/index/")
  10. def index():
  11. return render_template("index.html", **dic)
  12. if __name__ == "__main__":
  13. # app.config.from_pyfile('settings.py',silent=True)
  14. app.run(debug=True)

模板部分:(为了防止外来代码注入带来的影响,所以会自动将其转义)

  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="UTF-8">
  5. <title>Title</title>
  6. </head>
  7. <body>
  8. <input type="text" class="query" id="upquery" name="query" maxlength="100" len="80" onfocus="focusInput(this)" ov="汇拼" value="汇拼" autocomplete="off">
  9. <!-- 自动转义 -->
  10. <h1>{{ es }}</h1>
  11. </body>
  12. </html>

网页显示:
image.png
解决方案:
第一种方式:局部不转义{% autoescape off %} {% endautoescape %} 适用于代码块

  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="UTF-8">
  5. <title>Title</title>
  6. </head>
  7. <body>
  8. <input type="text" class="query" id="upquery" name="query" maxlength="100" len="80" onfocus="focusInput(this)" ov="汇拼" value="汇拼" autocomplete="off">
  9. <!-- 自动转义 -->
  10. {% autoescape off %}
  11. <h1>{{ es }}</h1>
  12. {% endautoescape %}
  13. </body>
  14. </html>

第二种方式:safe过滤器定义安全,适用于少量,离散代码

  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="UTF-8">
  5. <title>Title</title>
  6. </head>
  7. <body>
  8. <input type="text" class="query" id="upquery" name="query" maxlength="100" len="80" onfocus="focusInput(this)" ov="汇拼" value="汇拼" autocomplete="off">
  9. <!-- 自动转义 -->
  10. <!-- 标记它是安全的 -->
  11. <h1>{{ es|safe }}</h1>
  12. </body>
  13. </html>

网页显示,代码生效:
image.png
3、 truncate过滤器( truncate(value,length=255,killwords=False):截取length长度的字符串)
代码部分:

  1. from flask import Flask, render_template
  2. app = Flask(__name__)
  3. app.config["TEMPLATES_AUTO_RELOAD"] = True
  4. @app.route("/")
  5. def home():
  6. return "首页"
  7. dic = {
  8. "bookname":"早安世界,如果天上有一抹色彩" # 在这里
  9. }
  10. @app.route("/index/")
  11. def index():
  12. return render_template("index.html", **dic)
  13. if __name__ == "__main__":
  14. # app.config.from_pyfile('settings.py',silent=True)
  15. app.run(debug=True)

模板部分:

  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="UTF-8">
  5. <title>Title</title>
  6. </head>
  7. <body>
  8. <h1>{{ bookname|truncate(length=4) }}</h1>
  9. </body>
  10. </html>

网页返回:由于存在小小的问题所以我选择了自定义过滤器@app.template_filter(“模板调用时使用的过滤器名称”)详细见3
image.png

3、自定义过滤器(@app.template_filter(“模板调用时使用的过滤器名称”))

第一个小例子:完成对输入内容进行部分省略

  1. from flask import Flask, render_template
  2. app = Flask(__name__)
  3. app.config["TEMPLATES_AUTO_RELOAD"] = True
  4. @app.route("/")
  5. def home():
  6. return "首页"
  7. dic = {
  8. "bookname":"早安世界,如果天上有一抹色彩"
  9. }
  10. @app.route("/index/")
  11. def index():
  12. return render_template("index.html", **dic)
  13. @app.template_filter("truncate") # 代码在这里
  14. # 传入需要显示的字符串长度
  15. def truncate(value,length):
  16. # 如果输入的length大于字符的长度则输出全字符加...
  17. if len(value)<length:
  18. return value + "..."
  19. # 如果输入在正常范围
  20. elif 0<length and length<len(value):
  21. return value[:length] + "..."
  22. if __name__ == "__main__":
  23. # app.config.from_pyfile('settings.py',silent=True)
  24. app.run(debug=True)

然后在模板中进行调用就可以了

第二个小例子:完成不同时间的显示
代码部分:**

  1. from datetime import datetime
  2. from flask import Flask, render_template
  3. app = Flask(__name__)
  4. app.config["TEMPLATES_AUTO_RELOAD"] = True
  5. dic = {
  6. "bookname": "早安世界,如果天上有一抹色彩",
  7. "time": datetime(2020, 4, 13, 13, 23, 6),
  8. "nowtime": datetime.now()
  9. }
  10. @app.route("/")
  11. def home():
  12. return "首页"
  13. @app.route("/index/")
  14. def index():
  15. return render_template("index.html", **dic)
  16. @app.template_filter("handle_time")
  17. def handle_time(time):
  18. if isinstance(time, datetime):
  19. now = datetime.now()
  20. # 转化为间隔为几秒
  21. timestamp = (now - time).total_seconds()
  22. if timestamp < 60:
  23. return "刚刚"
  24. elif 60 <= timestamp and timestamp < 60*60:
  25. return f"{timestamp//60}分钟之前"
  26. elif 60*60 <= timestamp and timestamp < 60*60*24:
  27. return f"{timestamp//(60*60)}小时之前"
  28. elif 60*60*24 <= timestamp:
  29. return f"{timestamp//(60*60*24)}天之前"
  30. else:
  31. return time
  32. if __name__ == "__main__":
  33. # app.config.from_pyfile('settings.py',silent=True)
  34. app.run(debug=True)

模板部分:

  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="UTF-8">
  5. <title>Title</title>
  6. </head>
  7. <body>
  8. <h1>文章发布时间:{{ time }}</h1>
  9. <h1>当前时间:{{ nowtime }}</h1>
  10. <!-- 调用handle_time过滤器 -->
  11. <h1>{{ time|handle_time }}</h1>
  12. </body>
  13. </html>

页面显示:
image.png

4、过滤器的连用

在符合业务逻辑的前提下可以使用过滤器的连用

  1. <h1>{{ es|safe|length }}</h1>