赞
踩
网站如何向客户端发送一个漂亮的页面呢
html
、css
、js
但是如果将这些字段都写到视图中,作为HttpResponse()
的参数响应给客户端,将会有以下问题
视图部分代码臃肿, 耦合度高
这样定义的字符串是不会出任何效果和错误的
效果无法及时查看.有错也不容易及时发现
解决问题
模板 Template
MVT设计模式中的T,Template
M全拼为Model
,与MVC中的M功能相同,负责和数据库交互,进行数据处理。
V全拼为View
,与MVC中的C功能相同,接收请求,进行业务处理,返回应答。
T全拼为Template
,与MVC中的V功能相同,负责封装构造要返回的html。
from flask import Flask
app = Flask(__name__)
@app.route("/")
def index():
return "<h3>Hell</h3><p>Flask</p>"
if __name__ == "__main__":
app.run(debug=True)
在 Flask中,配套的模板是 Jinja2
,Jinja2的作者也是Flask的作者。这个模板非常的强大,并且执行效率高。
templates
文件夹名称固定写法使用render_template()
使用模板
from flask import Flask,render_template
app = Flask(__name__)
@app.route("/")
def index():
return render_template("01_index.html")
if __name__ == "__main__":
app.run(debug=True)
<!DOCTYPE html> <html lang="en"> <head> <style> h1 { background-color: red; } p { background-color: blue; } </style> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>模板的使用</title> </head> <body> <h1>Hello模板的使用</h1> <p>这个是模板的使用案例</p> </body> </html>
在使用render_template渲染模版的时候,可以传递关键字参数
from flask import Flask,request,render_template from werkzeug.routing import BaseConverter app = Flask(__name__) @app.route("/") def index1(): return render_template("02_index.html",info="Flask模板传参") @app.route("/index2") def index2(): return render_template("02_index.html",info="python中的Flask模板传参",args="换了一个变量名") @app.route("/home") def home(): context = { "uname":"吕布", "age":18, "height":180, "arms":{"melee":"方天画戟","range":"弓箭","transport":"赤兔马"} } return render_template("02_index.html",**context) if __name__ == "__main__": app.run(debug=True)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>模板传参</title>
</head>
<body>
<h1>模板传参</h1>
<p>这个是关于{{info}}的内容</p><hr>
<p>这是换了一个效果:{{args}}</p><hr>
<p>{{uname}}的年龄是{{age}}岁,身高是{{height}},他的近战武器是{{arms["melee"]}},远程武器是{{arms.get("range")}},他的坐骑是{{arms.transport}}</p>
</body>
</html>
解析出该函数映射的路由地址
from flask import Flask,render_template
app = Flask(__name__)
@app.route("/")
def index1():
return render_template("03_index.html")
@app.route("/home/")
def index2():
return render_template("03_index.html")
if __name__ == "__main__":
app.run(debug=True)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>url_for的使用</title>
</head>
<body>
<h1>url_for的使用</h1><hr>
<p>index1的路由是{{url_for("index1")}}</p><hr>
<p>index2的路由是{{url_for("index2")}}</p>
</body>
</html>
有时候我们想要在模版中对一些变量进行处理,那么就必须需要类似于Python中的函数一样,可以将这个值传到函数中,然后做一些操作。
在模版中,过滤器相当于是一个函数,把当前的变量传入到过滤器中,然后过滤器根据自己的功能,再返回相应的值,之后再将结果渲染到页面中
过滤器名 | 解释 | 举例 |
---|---|---|
abs(value) | 返回一个数值的绝对值 | -1 | abs |
int(value) | 将值转换为int类型 | |
float(value) | 将值转换为float类型 | |
string(value) | 将变量转换成字符串 | |
default(value,default_value,boolean=false) | 如果当前变量没有值,则会使用参数中的值来代替。如果想使用python的形式判断是否为false,则可以传递boolean=true。也可以使用or来替换 | name|default(‘xiaotuo’) |
safe(value) | 如果开启了全局转义,那么safe过滤器会将变量关掉转义 | content_html|safe |
escape(value)或e | 转义字符,会将<、>等符号转义成HTML中的符号 | content|escape |
first(value) | 返回一个序列的第一个元素 | |
format(value,*arags,**kwargs) | 格式化字符串 | |
last(value) | 返回一个序列的最后一个元素。 |
只有当系统提供的过滤器不符合需求后,才须自定义过滤器。
过滤器本质上就是一个函数。
如果在模版中调用这个过滤器,那么就会将这个变量的值作为第一个参数传给过滤器这个函数,
然后函数的返回值会作为这个过滤器的返回值。
需要使用到一个装饰器:@app.template_filter('过滤器名称')
from flask import Flask,render_template app = Flask(__name__) @app.template_filter("cut") # 自定义过滤器的名称 def cut(value): value = value.replace("你","我") return value @app.route("/") def index(): info = "你好啊" return render_template("07_index.html",info = info) if __name__ == "__main__": app.run(debug=True)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>自定义过滤器</title>
</head>
<body>
<h1>自定义过滤器</h1>
过滤前的数据{{ info }}<br>
过滤后的数据{{ info | cut }}<br>
</body>
</html>
操作发布新闻 与现在的时间间隔 **
from datetime import datetime from flask import Flask,render_template app = Flask(__name__) """实现类似朋友圈多少时间之前发布的信息""" # 假设数据库中的数据是2020/01/01 03:10:10 # 现在的时间是2022/10/31 08:10:10 @app.template_filter("handler_time") def handler_time(time): # 获取当前时间 now = datetime.now() # 相差时间由秒为单位 # total_seconds() 此方法的返回类型是一个数字,该数字是该时间段内覆盖的总秒数 temp_stamp = (now - time).total_seconds() if temp_stamp < 60: return "1分钟之前" elif 60*60 > temp_stamp >= 60: return "1小时之前" elif 24*60*60>temp_stamp>=60*60: hours = temp_stamp/(60*60) return f"{int(hours)}小时之前" elif 24*60*60*30>=temp_stamp>=24*60*60: day = temp_stamp/(60*60*24) return f"{int(day)}天以前" else: return "很久以前" @app.route("/") def index(): tmp_time = datetime(2022,10,31,10,10,19) return render_template("08_index.html",tmp_time = tmp_time) if __name__ == "__main__": app.run(debug=True)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>自定义时间过滤器的使用</title>
</head>
<body>
<h1>自定义时间过滤器的使用</h1>
数据过滤后:{{ tmp_time|handler_time}}
</body>
</html>
所有的控制语句都是放在{% ... %}
中,并且有一个语句{% endxxx %}
来进行结束
if
:if语句和python中的类似,可以使用>,<,<=,>=,==,!=
来进行判断,也可以通过and,or,not,()
来进行逻辑合并操作
from flask import Flask,render_template
app = Flask(__name__)
@app.route("/")
def index():
uname = "李四"
return render_template("09_index.html",uname = uname)
if __name__ == "__main__":
app.run(debug=True)
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>流程控制——选择结构</title> </head> <body> <h1>流程控制——选择结构</h1> {% if uname == "张三"%} 我是{{ uname }} {% else %} 我不是张三,而是{{ uname }} {% endif %} </body> </html>
练习
模拟登录页面
from flask import Flask,render_template,request app = Flask(__name__) @app.route("/") def index(): return render_template("10_index2.html") @app.route("/login") def login(): user = request.args.get("user") return render_template("10_index2.html",user=user) if __name__ == "__main__": app.run(debug=True)
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>选择结构</title> </head> <body> {% if not user %} <a href="/login?user='nick'">请登录</a> <span>免费注册</span> {% else %} <h1>欢迎 {{ user }} </h1> <h2>首页</h2> {% endif %} </body> </html>
实现九九乘法表
from flask import Flask,render_template
app = Flask(__name__)
@app.route("/")
def index():
return render_template("11_index.html")
if __name__ == "__main__":
app.run(debug=True)
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>九九乘法表</title> </head> <body> <table border="1"> {% for i in range(1,10) %} <tr> {% for j in range(1,i+1) %} <td>{{j}}*{{i}} = {{i*j}}</td> {% endfor %} </tr> {% endfor %} </table> </body> </html>
模板中的宏跟python中的函数类似,可以传递参数,但是不能有返回值。
可以将一些经常用到的代码片段放到宏中,然后把一些不固定的值抽取出来当成一个变量。
{% macro inp(type="text",name="",value="")%}
<input type="{{type}}" name={{name}} value="{{value}}">
{% endmacro %}
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>宏的使用</title> </head> {% import 'macros/common.html' as mc %} {% from "macros/common.html" import inp with context %} <body> <h1>未使用宏</h1> <tr> <td>用户名:</td> <td><input type="text" value="{{nick}}"></input></td><br> </tr> <tr> <td>密码:</td> <td><input type="password" name="" id=""></td><br> </tr> <tr> <td>登录:</td> <td><input type="submit" value="登录" name="" id=""></td> </tr> </body><hr> <body> <h1>宏的使用</h1> <tr> <td>用户名:</td> <td>{{inp(name="uname")}}</td><br> </tr> <tr> <td>密码:</td> <td>{{inp("password","pwd")}}</td><br> </tr> <tr> <td>登录:</td> <td>{{inp("submit",value="登录")}}</td> </tr> </body> </html> ```language
页面的复用
这个标签相当于是直接将指定的模版中的代码复制粘贴到当前位置。
include标签,如果想要使用父模版中的变量,直接用就可以了,不需要使用with context
。
include的路径,也是跟import一样,直接从templates
根目录下去找,不要以相对路径去找。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。