Flask(2)
模板 - Templates
一、什么是模板
1、模板:模板是一个包含响应文本的文件(通常是html文件),在Flask 中就是允许响应给用户看的网页。
2、该文件中允许包含"占位变量"来表示动态的内容,其具体值在请求中才能知道。"占位变量"最终会被真实的值所替换。
3、模板最终也会被解析成字符串再响应给客户端,这一过程通常称为"渲染"。
Flask中的模板是依赖于 Jinja2 的模板系统
二、模板的设置
默认情况下,Flask会在程序文件夹中的 templates 的子文件夹中搜索模板。
默认情况下,需要手动创建 templates 文件夹。
三、模板的渲染
1、作用:
在视图函数中,通过 return render_template()将模板文件(xx.html)渲染成字符串之后,再响应给客户端浏览器
2、函数:
render_template('xxx.html',arg1=value1,arg2=value2)
ex:return render_template('xxx.html')
1、参数1 : xxx.html ,要渲染给客户端的html模板文件
2、参数2 ~ n :要传递给模板动态显示的变量占位符,如果没有动态的变量占位符,则可以省略
3、返回值:字符串
1 from flask import Flask, render_template 2 3 app = Flask(__name__) 4 5 # 将 01-template.html 模板文件渲染成字符串再响应给客户端 6 @app.route('/01-template') 7 def template(): 8 # 将01-template.html渲染成字符串 9 # return render_template('01-template.html') 10 # 渲染01-template.html ,并传递变量 11 12 dic = { 13 'music':'绿光', 14 'author':'小强', 15 'qu':'小亮', 16 'singer':'小凡', 17 } 18 return render_template('01-template.html',params=dic) 19 20 21 if __name__ == "__main__": 22 app.run(debug=True)
1 <!DOCTYPE html> 2 <html lang="en"> 3 <head> 4 <meta charset="UTF-8"> 5 <title>Title</title> 6 <style> 7 h1{ 8 color:red; 9 } 10 </style> 11 </head> 12 <body> 13 <h1>歌名:《{{params.music}}》</h1> 14 <h1>作词: {{params.author}}</h1> 15 <h1>作曲: {{params.qu}}</h1> 16 <h1>演唱: {{params.singer}}</h1> 17 </body> 18 </html>
四、模板中的语法(重难点)
1、变量
变量是一种特殊的占位符,告诉模板引擎该位置的值是从渲染模板时的数据中获取出来的。
1、在视图中 :
@app.route('/')
def index():
return render_template('xxx.html',变量1=值1,变量2=值2,..)
ex:return render_template('xxx.html',name='laowang',age=35)
注意:name 和 age 就是要传递到 xxx.html 中的变量
2、在模板中:
{{变量名}}
<h1>{{name}}</h1>
练习:
在 01-template.html基础上,完成下列效果显示:
歌名 :《绿光》
作词 : 小强
作曲 : 小亮
演唱 : 小凡
1 from flask import Flask, render_template 2 3 app = Flask(__name__) 4 5 # 将 01-template.html 模板文件渲染成字符串再响应给客户端 6 @app.route('/01-template') 7 def template(): 8 music = '绿光' 9 author = '小强' 10 qu = '小亮' 11 singer = '小凡' 12 13 #locals() : 将当前函数内所有的局部变量封装成一个字典 14 print(locals()) 15 return render_template('01-template.html',params=locals()) 16 17 18 if __name__ == "__main__": 19 app.run(debug=True)
1 <!DOCTYPE html> 2 <html lang="en"> 3 <head> 4 <meta charset="UTF-8"> 5 <title>Title</title> 6 <style> 7 h1{ 8 color:red; 9 } 10 </style> 11 </head> 12 <body> 13 <h1>歌名:《{{params.music}}》</h1> 14 <h1>作词: {{params.author}}</h1> 15 <h1>作曲: {{params.qu}}</h1> 16 <h1>演唱: {{params.singer}}</h1> 17 </body> 18 </html>
----能够传递到模板中作为变量的数据类型都有:----
1 from flask import Flask, render_template 2 3 app = Flask(__name__) 4 5 class Person(object): 6 name = None 7 8 def say(self): 9 return "hello im a person" 10 11 #目的:能够传递到模板中作为变量的数据类型都有 12 @app.route('/02-var') 13 def var(): 14 uname = "my name is gebilaowang" 15 bookName = '钢铁是怎样炼成的' 16 author = '奥斯特罗夫斯基' 17 price = 32.5 18 list = ['漩涡鸣人','卡卡西','自来也','佐助'] 19 tup = ('水浒传','三国演义','红楼梦','西游记') 20 dic = { 21 'WMZ':'小魏', 22 'WWC':'隔壁老王', 23 'LZ':'小泽', 24 'MM':'小蒙', 25 } 26 person = Person() 27 person.name = "狮王.金毛" 28 print(locals()) 29 return render_template('02-var.html',params = locals()) 30 31 32 if __name__ == "__main__": 33 app.run(debug=True)
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <!-- 过滤器 --> <h1>capitalize:{{params.uname|capitalize}}</h1> <h1>upper:{{params.uname|upper}}</h1> <h1>title:{{params.uname|title}}</h1> <!-- {{params.uname}} : 变量不存在,但不会报错 {{params.uname.len}} : 当变量不存在时还试图去找对应的属性的话,则报错 --> <h1>用户名:{{params.uname}}</h1> <h1>bookName : {{params.bookName}} </h1> <h1>bookName : {{params['bookName']}}</h1> <h1>author:{{params.author}}</h1> <h1>price:{{params.price}}</h1> <!-- 获取列表中的第一个元素 --> <h1>list[0]:{{params.list[0]}}</h1> <h1>list.0:{{params.list.0}}</h1> <!-- 获取元组中的第二个元素 --> <h1>tup[1] : {{params.tup[1]}}</h1> <h1>tup.1 : {{params.tup.1}}</h1> <!-- 获取字典中键为LZ的值--> <h1>dic['LZ'] : {{params.dic['LZ']}}</h1> <h1>dic.LZ : {{params.dic.LZ}}</h1> <!-- 获取 person 对象的 name 属性值 --> <h1>person.name : {{params.person.name}}</h1> <!-- 获取 person 对象的 say() --> <h1>person.say() : {{params.person.say()}}</h1> </body> </html>
2、过滤器
1、什么是过滤器
过滤器是允许在变量输出显示之前改变变量的值
2、语法
{{变量|过滤器}}
Jinja2 模板中常见过滤器:
过滤器名 说明
capitalize 首字符变大写,其他字符变小写
lower 把值转换成小写
upper 把值转换成大写
title 把值中的每个单词的首字符变大写
trim 去掉值两边的空格
3、标签
1、什么是标签
每个标签表示的是不同的服务器端的功能
2、常用标签:
1、if标签
1)基本if结构
{% if 条件 %}
{% endif %}
2)if ... else ... 结构
{% if 条件 %}
满足条件时要运行的代码
{% else %}
不满足条件时要运行的代码
{% endif %}
3)if ... elif ... elif ... else
{% if 条件1 %}
满足条件1,要运行的代码
{% elif 条件2 %}
满足条件2,要运行的代码
{% elif 条件3 %}
满足条件3,要运行的代码
{% else %}
以上条件都不满足的时候,要运行的代码
{% endif %}
1 from flask import Flask, render_template 2 3 app = Flask(__name__) 4 5 #目的:练习变量和if标签 6 @app.route('/03-if') 7 def if_views(): 8 return render_template('03-if.html') 9 10 @app.route('/user/login') 11 def login(): 12 return "模拟登录的地址... ..." 13 14 15 if __name__ == "__main__": 16 app.run(debug=True)
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> {% if uname %} <h1>欢迎:{{uname}}</h1> {% else %} <h1> <a href="{{url_for('login')}}">登录</a> </h1> {% endif %} </body> </html>
2、for 标签
{% for 变量 in 元组|列表|字典 %}
{% endfor %}
在 Jinja2 模板的循环中,支持内部变量 - loop
loop作用:记载当前循环中的一些相关信息
loop 常用属性:
1)index
用法:loop.index
作用:记录当前循环的次数,从1开始记录
2)index0
用法:loop.index0
作用:同上,从0开始记录
3)first
用法:loop.first
作用:值为True,则表示当前循环是第一次循环
4)last
用法:loop.last
作用:值为True,则表示当前循环是最后一次循环
from flask import Flask, render_template app = Flask(__name__) @app.route('/04-for') def for_views(): list = ['孙悟空','猪八戒','周瑜','鲁班七号','孙尚香','大乔','沈梦溪'] dic = { 'SWK':'孙悟空', 'PJL':'潘金莲', 'XMQ':'西门庆', 'WDL':'武大郎', 'WWC':'王干娘', } return render_template('04-for.html',params = locals()) if __name__ == "__main__": 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 <!-- 将05-head.html包含进当前的模板文件中 --> 9 {% include '05-head.html' %} 10 11 <!-- 引入macro.html 并使用声明好的 宏 --> 12 {% import 'macro.html' as macros %} 13 <ul> 14 {% for str in params.list %} 15 {{macros.show_li(str)}} 16 {% endfor %} 17 </ul> 18 19 20 <!-- 声明一个宏 : 接收一个字符串参数,将该参数放在<p>打印输出 --> 21 {% macro showP(str) %} 22 <p style="background:orange;">{{str}}</p> 23 {% endmacro %} 24 <!-- 调用宏,循环遍历params.list,将遍历出来的每个数据都放在showP()中运行 --> 25 <h1>使用宏显示数据</h1> 26 {% for name in params.list %} 27 {{showP(name)}} 28 {% endfor %} 29 30 31 <!-- 循环遍历 params.list --> 32 {% for name in params.list %} 33 <!--<h1>{{name}}</h1>--> 34 <!-- 35 第一项:背景颜色设置为红色 36 最后一项:背景颜色设置为黄色 37 否则:背景颜色设置为 粉色 38 --> 39 <!--{% if loop.first %}--> 40 <!--<h1 style="background:red;">{{name}}</h1>--> 41 <!--{% elif loop.last %}--> 42 <!--<h1 style="background:yellow;">{{name}}</h1>--> 43 <!--{% else %}--> 44 <!--<h1 style="background:deeppink;">{{name}}</h1>--> 45 <!--{% endif %}--> 46 47 <h1 style="background: 48 {% if loop.first %} 49 red 50 {% elif loop.last %} 51 yellow 52 {% else %} 53 deeppink 54 {% endif %} 55 ;">{{name}}</h1> 56 57 {% endfor %} 58 <!-- 59 循环遍历 params.dic 60 输出所有的内容: KEY:VALUE 61 --> 62 <h1>遍历所有的key</h1> 63 {% for key in params.dic.keys() %} 64 <h2>{{key}}</h2> 65 {% endfor %} 66 <h1>遍历所有的value</h1> 67 {% for value in params.dic.values() %} 68 <h2>{{value}}</h2> 69 {% endfor %} 70 <h1>遍历所有的key和value</h1> 71 {% for key,value in params.dic.items() %} 72 <h2>{{key}}:{{value}}</h2> 73 {% endfor %} 74 </body> 75 </html>
1 <!DOCTYPE html> 2 <html lang="en"> 3 <head> 4 <meta charset="UTF-8"> 5 <title>Title</title> 6 </head> 7 <body> 8 <div class="container"> 9 <div class="top"> 10 网页头部内容(LOGO,分类,登录,注册) 11 </div> 12 <ul> 13 <li>导航1</li> 14 <li>导航2</li> 15 <li>导航3</li> 16 </ul> 17 </div> 18 </body> 19 </html>
{% macro show_p(str) %} <p style="background:#f60;">{{str}}</p> {% endmacro %} {% macro show_li(str) %} <li> <p style="font-size:20px;">内容:</p> <span style="color:orange;">{{str}}</span> </li> {% endmacro%}
3、macro 标签 (宏)
1、作用
相当于是在模板中声明函数
2、语法
使用 {% macro %} 标签声明宏
<!-- 声明 -->
{% macro 名称(参数列表) %}
xxxx xxxx
{% endmacro %}
<!-- 调用 -->
{{show(uname)}}
et:
<!-- 声明 -->
{% mscro show(str) %}
<h1>{{str}}</h1>
{% endmacro %}
<!-- 调用 -->
{{show(uname)}}
3、在独立的文件中声明宏
为了方便重复使用,允许将宏放在单独的模板文件中声明定义
1、创建 macro.html 模板文件
作用:定义项目中要用到的所有的宏
ex:{% mscro show(str) %}
<h1>{{str}}</h1>
{% endmacro %}
2、在使用的网页中,导入 macro.html
{% import 'macro.html' as macros %}
from flask import Flask, render_template app = Flask(__name__) @app.route('/05-static') def static_views(): return render_template('05-static.html') if __name__ == "__main__": 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 <img src="/static/images/wxy.jpeg"> 9 <img src="http://localhost:5000/static/images/wxy.jpeg" alt=""> 10 </body> 11 </html>
4、include 标签(模板的包含)
作用:将其他的模板文件包含到当前的模板文件中。
在多处重复使用的模板代码可以放在单独的文件中,可以被其他的模板所包含(引用)
语法:{% include 'xxx.html' %}
示例:见04-forhtml
五、静态文件处理
1、什么是静态文件
在Flask中不能与服务器动态交互的文件都是静态文件
如:图片,css文件,js文件,音视频文件,...
<img src="images/a.jpg">
<link rel="" href="css/a.css">
<script src="js/a.js"></script>
<video src="mp4/a.mp4"></video>
<audio src="music/a.mp3"></audio>
2、静态文件的处理
1、所有的静态文件必须放在名为 static 的目录中。static目录要放在项目的根目录处。
结构:
FlaskDemo02
run01.py
templates
01-xxx.html
02-xxx.html
static
images
a.jpg
b.jpg
js
body.js
slider.js
css
2、所有的静态文件必须通过 /static/ 路径访问
/static/images/a.jpg
/static 要到静态资源目录中继续搜索
ex:<img src="/static/资源路径">
3、静态文件地址的反向解析:
url_for('static',filename='<file_path>')
ex:
<img src="{{url_for('static',filename='images/b04.jpg')}}">
结果:/static/images/b04.jpg
from flask import Flask, render_template, url_for, request app = Flask(__name__) # 访问路径 http://localhost:5000/01-static @app.route('/01-static') def static_views(): url = url_for('static',filename='images/b05.jpg') print(url) return render_template('01-static.html') if __name__ == '__main__': app.run(debug=True,host='0.0.0.0')
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <img width="300" src="{{ url_for('static',filename='images/b05.jpg') }}"> </body> </html>
六、模板的继承
1、什么是模板的继承
模板的继承类似于类的继承,如果在一个模板中出现的大量内容是另外一个模板的话,那么就可以使用继承的方式来简化开发
2、语法
1、父模板
需要定义出哪些内容在子模板中是可以被重写的
{% block 块名 %}
父模板中正常显示的内容
{% endblock %}
block:
定义允许在子模板中被修改的内容
1、在父模板中是可以正常显示的,没有任何影响
2、在子模板中是可以被重写的
from flask import Flask, render_template, url_for, request app = Flask(__name__) # 访问路径 http://localhost:5000/02-parent @app.route('/02-parent') def parent_views(): return render_template('02-parent.html') if __name__ == '__main__': app.run(debug=True,host='0.0.0.0')
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <h1> <a href="/04-request">去往04-request</a> </h1> <h1>这是parent的头部</h1> {% block content %} <h1>这是parent的主体内容</h1> {% endblock %} <h1>这是parent的底部</h1> </body> </html>
2、子模板
1、需要指定继承来自哪个父模板
使用 {% extends '父模板名称' %} 来完成继承
2、重写父模板中对应内容
使用 {% block 块名 %} 来重写父模板中的同名内容
{% block 块名 %}
此处编写的内容会覆盖掉父模板中同名block的内容。
允许通过 {{super()}} 来调用父模板中的内容。
{% endblock %}
ex:
{% extends '02-parent.html' %}
{% block content %}
{{ super() }}
<h1 style="color: red;">这是child主体</h1>
{% endblock %}
from flask import Flask, render_template, url_for, request
app = Flask(__name__)
# 访问路径 http://localhost:5000/03-child
@app.route('/08-child')
def child_views():
return render_template('08-child.html')
if __name__ == '__main__':
app.run(debug=True,host='0.0.0.0')
{% extends '07-parent.html' %} {% block content %} {{ super() }} <h1 style="color:red;">这是 07-child 中的内容</h1> {% endblock %}
七、修改配置
1、构建Flask 应用允许的指定配置信息
app = Flask(__name__,template_folder='muban',static_url_path='/s',static_folder='/sta')
1.template_folder
指定存放模板的文件夹名称(设置模板的保存路径)
2.static_url_path
访问静态资源的路径(设置静态文件的访问路径,即映射到WEB中的访问路径)
http://localhost:5000/s/xxx 查找静态资源文件
3.static_folder
指定存放静态文件的目录名称(映射到项目中的目录名称)
在项目的根目录中 ,有一个名为 sta 的目录用于存放静态文件。
2、启动程序的运行配置
app.run(debug = True,port = 5555,host = '0.0.0.0')
host : 指定访问地址,0.0.0.0 表示局域网内的任何机器都可以访问网站
查看ip:ifconfig
posted on 2018-11-07 21:18 破天荒的谎言、谈敷衍 阅读(273) 评论(0) 收藏 举报
浙公网安备 33010602011771号