一、模板的基本使用
1、设置模板文件路径:template_folder='路径'
from flask import Flask,render_template # template_folder='D:\templates' => 可指定模板路径 默认值为:templates app = Flask(__name__,template_folder='templates')
1.1:最简单的模板语法
# <p>我是<h1>{{ a }}</h1>参数参数参数参数参数参数</p> @app.route('/') def home(): a = "后台传过来的" return render_template('index.html',a=a)
1.2:可以使用**对模板语法进行批量的方式传到前端
""" <body> <div> <p>{{ name }}</p> <p>{{ age }}</p> <p>{{ sex }}</p> </div> ==================== <div> {{ dicts.aa }} {{ dicts['aa'] }} </div> </body> """ @app.route('/list/') def list(): context = { 'name':'lee', 'age':18, 'sex':'男', 'dicts':{ 'aa':'aa', 'bb':'bb' }, } return render_template('posts/list.html',**context)
2、对 url_for() 的使用:
语法:{{url_for('视图函数名或别名',arg1=arg1,arg2=arg2,arg3=arg3)}}
注:如果链接中有参数arg则会补位到链接中不会以GET方式携带
# <p><a href="{{ url_for('login',next='/',ref = 77908,uid=15) }}">登陆</a></p> # =>>> http://127.0.0.1:5000/login/15/?next=%2F&ref=77908 @app.route('/') def index(): return render_template('index.html') @app.route('/login/<uid>/') def login(uid): print(uid) return render_template('login.html')
二、模板的高级使用
语法:变量名 | 过滤器
{{args | filter_func}}
在 jinja2 中,过滤器是可以支持链式调用的,示例如下:
{{ "hello world" | reverse | upper }}
1.内置过滤器
1.1字符串相关
safe :禁用转义
{{ '<em>hello</em>'|safe}} <br>
default:默认值
{{ name | default('默认值',boolean=True) }}
capitalize:首字母大写
{{ 'hello world' | capitalize }}
lower 把所有字母转换为小写
{{ 'HELLO'|lower }}
upper 把所有字母转换成大写
{{ 'hello' | upper }}
title 把值里面的每个单词的首字母大写
{{ 'big big world' | title }}
trim 把值的首尾空格去掉
{{ ' hello ' |trim }}
reverse :字符串反转
{{ 'hello' | reverse }}
format:格式化输出
{{ "%s is %d" | format("ryang",24) }}
striptags:渲染之前把值中所有的HTML标签都删掉
<p>{{ '<em>hello</em>' | striptags }}</p>
truncate: 字符串截断
<p>{{ 'hello every one' | truncate(9)}}</p>
1.2列表操作
first :取第一个元素
{{ [3,4,5,6,7]|first }}
last:取最后一个元素
{{ [3,4,5,6,7]|last }}
length:获取列表的长度
{{ [1,2,3,4,5,6]|length }}
sum:列表求和
{{ [1,2,3,4,5,6]|sum }}
sort:列表排序
{{ [4,5,6,2,1]|sort }}
语句块过滤:
{% filter upper %} this is a Flask Jinja2 introduction {% endfilter %}
2.自定义过滤器
注:设置TEMPLATES_AUTO_RELOAD = True,将会自动加载模板
# {{ eat | filter_cut }} => ! my eat apple @app.route('/') def index(): context = { 'eat' : "hello ! my eat apple" } return render_template('index.html',**context) # 定义过滤器函数 # 将cut函数注册到过滤器使用名字为filter_cut @app.template_filter('filter_cut') def cut(value): value = value.replace('hello','') return value
案例:时间过滤器
import datetime # <p>此信息更新于{{ creat_time | handle_time }}</p> @app.route('/') def index(): context = { 'creat_time':datetime.datetime(2020,1,20,16,0,0) } return render_template('index.html',**context) # 定义过滤器函数 # 将cut函数注册到过滤器使用名字为filter_cut @app.template_filter('handle_time') def handle_time(value): """ 1分钟以内就显示‘刚刚’ 1小时以内就显示‘**分钟前’ 1天以内就显示‘**小时前’ 1-30天显示‘**天’ 其他显示具体日期 :param value: :return: """ if isinstance(value,datetime.datetime): now = datetime.datetime.now() timestamp = (now - value).total_seconds() if timestamp < 60: return '刚刚' elif timestamp>=60 and timestamp<=60*60: return '{}分钟前'.format(int(timestamp / 60)) elif timestamp>=60*60 and timestamp<=60*60*24: return '{}小时前'.format(int(timestamp / (60*60))) elif timestamp>=60*60*24 and timestamp<=60*60*24*30: return '{}天前'.format(int(timestamp / (60*60*24))) else: return value else: return value
3.宏用法:类似于创造一个函数,将函数在模板中以变量的方式展示,如下所示
<body> {% macro input(name,value="",type="text") %} <input type="{{ type }}" name="{{ name }}" value="{{ value }}"> {% endmacro %} <table> <tbody> <tr> <td>用户名:</td> <td>{{ input("username") }}</td> </tr> <tr> <td>密码:</td> <td>{{ input("pass",type="password") }}</td> </tr> <tr> <td></td> <td>{{ input(value="提交",type="submit") }}</td> </tr> </tbody> </table> </body>
4.不常用的模板变量
4.1:set
{% set username = "daojiale" %} <p>{{ username }}</p>
4.2:with
{% with classroom="kebo" %} {# with语句只能在代码块中定义和执行 #} <p>第一次使用:{{ classroom }}</p> {% endwith %} <p>第二次使用:{{ classroom }}</p>
5.使用静态问卷:css、js、image等
<link rel="stylesheet" href="{{ url_for('static',filename="css/index.css") }}"> <img src="{{ url_for('static',filename='img/1.jfif') }}" alt=""> <script src="{{ url_for('static',filename='js/index.js') }}"></script>
5.模板继承
--- base.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> </head> <body> <div> <p>固定顶部</p> </div> {% block title %} <p>我是base.html中的代码块,在其他地方引用就用 self.模块名() </p> {% endblock %} {% block body_c %} 我是父模板内容 {% endblock %} <div> <p>固定底部</p> </div> </body> </html>
--- index.html
{% extends 'base/base.html'%} {% block body_c %} <hr> {{ self.title() }} {{ super() }} 我是子模板内容:使用super()方法可以将父模板内容和子模板内容同时展示 <div> 1.extends 继承哪个模板; </div> <div> 2.block 使用继承模板中的具体位置; </div> <div> 3.在block代码块中写变化的内容; </div> <hr> {% endblock %}