Flask进阶
1. cookie
创建flask_demo15_cookie.py
"""
cookie
- 解释:用来保持服务器和浏览器交互的状态的,由服务器设置,存储在浏览器
- 作用:用来做广告推送
- cookie的设置和获取
- 设置cookie:response.set_cookie(key, value, max_age)
- max_age: 表示cookie在浏览器的存储时间,单位:秒
- 获取cookie:request.cookies.get("key")
"""
from flask import Flask, make_response, request
app = Flask(__name__)
# 设置cookie
@app.route("/set_cookie")
def set_cookie():
# 调用 make_response() 方法获取响应体对象
response = make_response()
# 设置 cookie
response.set_cookie("computer", "lenovo")
# 设置 cookie 20秒后过期
response.set_cookie("age", "23", 20)
return response
# 设置cookie
@app.route("/get_cookie")
def get_cookie():
# 获取 cookie
name = request.cookies.get("computer")
age = request.cookies.get("age")
# 返回
return f"name is {name}, age is {age}"
@app.route("/")
def helloworld():
return "hello world Flask"
if __name__ == "__main__":
app.run(debug=True)
2.session
创建flask_demo16_session.py
"""
session
- 解释:服务器和用户来做状态保持的,里面存储的是敏感信息(比如身份证、登录信息),由服务器设置,并存储在服务器
- 作用:用来做用户的登录状态保持
- session的设置和获取
- 设置 session: session[key] = value
- 获取 session: value = session.get(key)
- 注意:
- session的存储依赖于 cookie
- 存储在 cookie 中的 sessionID需要加密,需要设置 SECRET_KEY
"""
from flask import Flask, session
app = Flask(__name__)
# 设置 SECRET_KEY
app.config["SECRET_KEY"] = "DSFALSDJEsdlj32s"
# 设置 session
@app.route("/set_session/<path:name>")
def set_session(name):
session["name"] = name
return "set session"
# 获取 session
@app.route("/get_session")
def get_session():
name = session.get("name")
return f"set session, name is {name}"
@app.route("/")
def helloworld():
return "hello world Flask"
if __name__ == "__main__":
app.run(debug=True)
3.上下文
创建flask_demo17_content.py
"""
上下文【了解】
- 解释:就是一个容器
- 请求上下文
- request: 封装的是请求相关的数据
- session: 封装的是和用户相关的敏感信息
- 应用上下文【在项目中具体应用】
- current_app: 是app的一个代理对象,可以通过他获取app身上设置的各种属性,主要用在模块化开发中
- g: 一个局部的全局变量,主要用在装饰器中
"""
from flask import Flask, current_app
app = Flask(__name__)
@app.route("/")
def helloworld():
print(app.config.get("DEBUG"))
print(current_app.config.get("DEBUG"))
return "hello world Flask"
if __name__ == "__main__":
app.run(debug=True)
4.render_template
创建flask_demo18_render_template.py
"""
render_template【掌握】
- 解释:属于jinjia2的模板函数
- 好处:
- 1. 以后的视图函数,只负责业务逻辑的处理,比如:数据库的增删改查
- 2. 以后数据的展示,全部都由jinjia2的模板负责
- 使用格式:
- response = render_template('模板文件')
"""
from flask import Flask, render_template
app = Flask(__name__)
@app.route("/")
def helloworld():
response = render_template("Ademo01.html")
return response
if __name__ == "__main__":
app.run(debug=True)
创建templates目录,在该目录下创建Ademo01.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Ademo01</title>
</head>
<body>
<h1>欢迎!</h1>
<h2>各种变量的值</h2>
<ul>
<li>
整数:{{number}}
</li>
<li>
字符串:{{str}}
</li>
<li>
元组:{{tuple}}
<br>
元组元素:{{tuple.0}}、{{tuple[1]}}、{{tuple.2}}、{{tuple[3]}}、{{tuple.4}}
</li>
<li>
列表:{{list}}
<br>
列表元素:{{list.0}}、{{list[1]}}、{{list.2}}、{{list[3]}}、{{list.4}}
</li>
<li>
字典:{{dict}}
<br>
<!-- 字典用 [] 取值时,内部参数须是字符串类型 -->
字典元素:{{dict.name}}、{{dict["age"]}}
</li>
</ul>
</body>
</html>
variable
创建flask_demo19_variable.py
"""
模板语法:获取变量【理解】
- 解释:在模板中获取视图函数的变量
- 格式:
- {{ 变量 }}
"""
"""
render_template【掌握】
- 解释:属于jinjia2的模板函数
- 好处:
- 1. 以后的视图函数,只负责业务逻辑的处理,比如:数据库的增删改查
- 2. 以后数据的展示,全部都由jinjia2的模板负责
- 使用格式:
- response = render_template('模板文件')
注意:如果发现程序端口被占用
- 1. lsof -i:5000
- 2. kill [端口号]
"""
from flask import Flask, render_template
app = Flask(__name__)
@app.route("/")
def helloworld():
# 1. 定义各种类型的变量
number = 10
str = "木婉清"
tuple = (1, 2, 3, 4, 5)
list = [6, 7, 8, 9, 10]
dict = {"name": "木婉清", "age": 23}
# 2. 携带变量到模板中展示
return render_template(
"Ademo01.html", number=number, str=str, tuple=tuple, list=list, dict=dict
)
if __name__ == "__main__":
app.run(debug=True)
other_program
创建flask_demo20_other_program.py
from flask import Flask, render_template
app = Flask(__name__)
@app.route("/")
def helloworld():
# 1. 定义各种类型的变量
number = 10
str = "木婉清"
tuple = (1, 2, 3, 4, 5)
list = [6, 7, 8, 9, 10]
dict = {"name": "木婉清", "age": 23}
# 2. 携带变量到模板中展示
return render_template(
"Ademo02_other_program.html",
number=number,
str=str,
tuple=tuple,
list=list,
dict=dict,
)
if __name__ == "__main__":
app.run(debug=True)
创建templates/Ademo02_other_program.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Ademo01</title>
</head>
<body>
<h1>欢迎!</h1>
<h2>遍历元组中的偶数</h2>
{% for i in tuple %}
{% if i %2 == 0 %}
{{i}}
{% endif %}
{% endfor %}
<h2>遍历字典</h2>
{%for k, v in dict.items()%}
{{k}}:{{v}}
{%endfor%}
</body>
</html>
string_filter
创建flask_demo21_string_filter.py
from flask import Flask, render_template
app = Flask(__name__)
@app.route("/")
def helloworld():
return render_template("Ademo03_stringFilter.html")
if __name__ == "__main__":
app.run(debug=True)
创建templates/Ademo03_stringFilter.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>string-filter</title>
</head>
<body>
safe: 禁止转义,让标签生效
<!-- 没加safe,输出<em>hello</em> -->
<p>{{'<em>hello</em>'}}</p>
<!-- 加了safe,输出斜体的hello -->
<p>{{'<em>hello</em>'|safe}}</p>
capitalize: 把变量值的首字母转成大写,其余字母转小写
<p>{{'hello world'|capitalize}}</p>
lower: 把值转成小写
<p>{{'HELLO'|lower}}</p>
upper: 把值转成大写
<p>{{'hello'|upper}}</p>
title: 把值中的每个单词的首字母都转成大写
<p>{{'hello world'|title}}</p>
reverse: 字符串反转
<p>{{'olleh'|reverse}}</p>
format: 格式化输出
<p>{{'%s is %d'|format('name', 17)}}</p>
striptags: 渲染之前把值中的所有的HTML标签都删掉
<p>{{'<em>hello</em>'|striptags}}</p>
</body>
</html>
list_filter
创建flask_demo22_list_filter.py
from flask import Flask, render_template
app = Flask(__name__)
@app.route("/")
def helloworld():
return render_template("Ademo04_listFilter.html")
if __name__ == "__main__":
app.run(debug=True)
创建templates/Ademo04_listFilter.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>listFilter</title>
</head>
<body>
<h1>列表过滤器</h1>
first: 取第一个元素
<p>{{[1, 2, 3, 4, 5, 6]|first}}</p>
last: 取最后一个元素
<p>{{[1, 2, 3, 4, 5, 6]|last}}</p>
length: 获取列表长度
<p>{{[1, 2, 3, 4, 5, 6]|length}}</p>
sum: 列表求和
<p>{{[1, 2, 3, 4]|sum}}</p>
sort: 列表排序,默认升序
<p>{{[6, 5, 4, 3, 2, 1]|sort}}</p>
过滤器的链式调用
<p>{{'hello'| upper | reverse}}</p>
</body>
</html>
custom_filter
创建flask_demo23_custom_filter.py
"""
自定义过滤器【掌握】
- 解释:当系统提供的过滤器满足不了需求的时候,需要自定义
- 自定义过滤器有两种格式:
- 1. 先定义好函数,再将函数添加到系统默认的过滤器列表中
- def 函数名(): pass
- app.add_template_filter(函数名, '过滤器名字')
- 2. 定义函数的时候,直接使用系统过滤器进行装饰
@app.template_filter('过滤器名字')
def 函数名():
pass
- 案例:
- 1. 获取列表偶数和
- 2. 翻转列表
"""
from flask import Flask, render_template
app = Flask(__name__)
# 1. 先定义好函数,再将函数添加到系统默认的过滤器列表中
def get_evenNumber(list): # 获取偶数和
sum = 0
for i in list:
if i % 2 == 0:
sum += i
return sum
# 参数1:关联的函数的名字;参数2:在模板中使用的过滤器的名字
app.add_template_filter(get_evenNumber, "evenNumber")
# 2. 定义函数的时候,直接使用系统过滤器进行装饰
@app.template_filter("list_reverse")
def list_reverse(list): # 列表反转
list.reverse() # 直接返回的结果是 None
return list
@app.route("/")
def helloworld():
return render_template("Ademo05_custom_filter.html")
if __name__ == "__main__":
app.run(debug=True)
创建templates/Ademo05_custom_filter.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>custom_filter</title>
</head>
<body>
<h2>原列表:{{[1, 2, 3, 4, 5, 6]}}</h2>
<h2>偶数列表:{{[1, 2, 3, 4, 5, 6] | evenNumber}}</h2>
<h2>原列表:{{[1, 2, 3, 4, 5, 6]}}</h2>
<h2>反转列表:{{[1, 2, 3, 4, 5, 6] | list_reverse}}</h2>
</body>
</html>
macro
创建flask_demo24_macro.py
"""
代码复用——宏【了解】
解释:相当于 python 中的函数,定义好一段功能,在需要的时候进行调用
"""
from flask import Flask, render_template
app = Flask(__name__)
@app.route("/")
def helloworld():
response = render_template("Ademo06_macro.html")
return response
if __name__ == "__main__":
app.run(debug=True)
创建templates/Ademo06_macro.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>macro</title>
</head>
<body>
<!-- 定义宏 -->
{% macro my_macro(name, password)%}
用户名:<input type="text" value="{{name}}"><br>
密码:<input type="password" value="{{password}}"><br>
{% endmacro %}
<!-- 调用当前文件宏 -->
{{ my_macro("木婉清", '123456') }}
<!-- 调用其他文件的宏 -->
{% import 'Ademo07_other_macro.html' as other %}
{{ other.my_input() }}
{{ other.my_div() }}
</body>
</html>
创建templates/Ademo07_other_macro.html
<!-- 定义宏 -->
{% macro my_macro(name, password)%}
用户名:<input type="text" value="{{name}}"><br>
密码:<input type="password" value="{{password}}"><br>
{% endmacro %}
{% macro my_input()%}
输入框:<input type="text" value="{{name}}"><br>
{% endmacro %}
{% macro my_div()%}
<div>div</div>
{% endmacro %}
extends
创建flask_demo25_extends.py
"""
代码复用——继承
- 解释:一个子模版继承自父模板
- 作用:共性抽取,代码复用
- 父模板:
- 所有子类都具有的相同的内容,在父模板中直接写死
- 每个子类的模板中不一样的内容,使用block模板定义好
- 子模板:
- 根据子类自己的需求,去重写父类中的block对应的内容
- 如果重写之后,还想保留父类的内容,那么使用{{super()}}
- 继承格式:{% extends '父文件名' %},写在页面的顶部
- 注意点:
定义block的格式
{% block 名称 %}
{% endblock %}
"""
from flask import Flask, render_template
app = Flask(__name__)
@app.route("/")
def helloworld():
response = render_template("Ademo08_extends_son.html")
return response
@app.route("/index")
def index():
response = render_template("Ademo09_extends_son2.html")
return response
if __name__ == "__main__":
app.run(debug=True)
创建templates/Ademo08_extends_son.html
{% extends 'Ademo10_extends_base.html' %}
{% block contentBlock %}
<p>
床前明月光<br>
疑是地上霜<br>
举头望明月<br>
低头思故乡<br>
</p>
{% endblock %}
{% block footBlock %}
<div>
<a href="/index">点我有惊喜!</a>
</div>
{% endblock %}
创建templates/Ademo09_extends_son2.html
{% extends 'Ademo10_extends_base.html' %}
{% block contentBlock %}
<p>
床前明月光<br>
李白睡的香<br>
梦见牛魔王<br>
吓得尿裤裆<br>
</p>
{% endblock %}
{% block footBlock %}
<div>
<a href="/">点我有惊喜!</a>
</div>
{% endblock %}
创建templates/Ademo10_extends_base.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>extends</title>
</head>
<body>
<!-- 头部部分 -->
{% block titleBlock %}
<h1>静夜思</h1>
{% endblock %}
<!-- 正文部分 -->
{% block contentBlock %}
{% endblock %}
<!-- 底部部分 -->
{% block footBlock %}
<div>
<a href="#">点我有惊喜!</a>
</div>
{% endblock %}
</body>
</html>
include
创建flask_demo26_include.py
"""
包含
"""
from flask import Flask, render_template
app = Flask(__name__)
@app.route("/")
def helloworld():
response = render_template("Ademo11_include.html")
return response
if __name__ == "__main__":
app.run(debug=True)
创建templates/Ademo11_include.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>include</title>
</head>
<body>
<!-- ignore missing保证不存在该html页面也不会报错 -->
{%include 'Ademo03_stringFilter.html' ignore missing%}
</body>
</html>
practice
创建flask_demo27_practice.py
from flask import Flask, render_template
app = Flask(__name__)
my_list = [
{"id": 1, "value": "我爱工作"},
{"id": 2, "value": "工作使人快乐"},
{"id": 3, "value": "沉迷于工作无法自拔"},
{"id": 4, "value": "日渐消瘦"},
{"id": 5, "value": "以梦为马,越骑越慢"},
]
@app.route("/")
def helloworld():
response = render_template("Ademo12_practice.html", my_list=my_list)
return response
if __name__ == "__main__":
app.run(debug=True)
创建templates/Ademo12_practice.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>practice</title>
</head>
<body>
<ul>
<!-- 在 for 中使用 if -->
{%for dict in my_list if dict.id != 5 %}
{% if loop.index == 1 %}
<li style="background: yellow;">{{dict.value}}</li>
{% elif loop.index == 2 %}
<li style="background: green;">{{dict.value}}</li>
{% elif loop.index == 3 %}
<li style="background: red;">{{dict.value}}</li>
{% else %}
<li style="background: purple;">{{dict.value}}</li>
{% endif %}
<!-- 从0开始的索引 -->
<!-- <h3>{{loop.index0}}</h3> -->
<!-- 从1开始的索引 -->
<!-- <h3>{{loop.index}}</h3> -->
{%endfor%}
</ul>
</body>
</html>
flash
创建flask_demo28_flash.py
from flask import Flask, render_template, flash
app = Flask(__name__)
app.config["SECRET_KEY"] = "sadljf"
@app.route("/")
def helloworld():
# 存储消息
flash("登录成功")
response = render_template("Ademo13_flash.html")
return response
@app.route("/error")
def error():
# 存储消息
flash("登录失败")
return "error"
if __name__ == "__main__":
app.run(debug=True)
创建templates/Ademo13_flash.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>flush</title>
</head>
<body>
{{get_flashed_messages()}}
</body>
</html>