Flask介绍
分类:
IT文章
•
2024-04-22 16:56:58
原文地址:http://www.cnblogs.com/wupeiqi/articles/5341480.html
Flask是一个基于Python开发并且依赖jinja2模板和Werkzeug WSGI服务的一个微型框架.
Werkzeug本质就是Socket服务端,其用于接收http请求并对请求进行预处理,然后触发Flask框架,开发人员基于Flask框架提供的功能对请求进行相应的处理,并返回给用户,如果返回给用户的内容很复杂,就需要借助jinja2模板引擎来实现对模板的处理,即:将模板和数据进行渲染,将渲染后的字符串数据返回给用户浏览器。
“微”(micro) 并不表示你需要把整个 Web 应用塞进单个 Python 文件(虽然确实可以 ),也不意味着 Flask 在功能上有所欠缺。微框架中的“微”意味着 Flask 旨在保持核心简单而易于扩展。Flask 不会替你做出太多决策——比如使用何种数据库。而那些 Flask 所选择的——比如使用何种模板引擎——则很容易替换。除此之外的一切都由可由你掌握。如此,Flask 可以与您珠联璧合。
默认情况下,Flask 不包含数据库抽象层、表单验证,或是其它任何已有多种库可以胜任的功能。然而,Flask 支持用扩展来给应用添加这些功能,如同 Flask 本身实现的一样。众多的扩展提供了数据库集成、表单验证、上传处理、各种各样的开放认证技术等功能。Flask 也许是“微小”的,但它已经准备好在需求繁杂的生产环境中投入使用。
另外的介绍:
Flask诞生于2010年,是Armin ronacher(人名)用 Python 语言基于 Werkzeug 工具箱编写的轻量级Web开发框架。
Flask 本身相当于一个内核,其他几乎所有的功能都要用到扩展(邮件扩展Flask-Mail,用户认证Flask-Login,数据库Flask-SQLAlchemy),都需要用第三方的扩展来实现。比如可以用 Flask 扩展加入ORM、窗体验证工具,文件上传、身份验证等。Flask 没有默认使用的数据库,你可以选择 MySQL,也可以用 NoSQL。
其 WSGI 工具箱采用 Werkzeug(路由模块),模板引擎则使用 Jinja2。这两个也是 Flask 框架的核心。
Flask常用扩展包:
- Flask-SQLalchemy:操作数据库;
- Flask-script:插入脚本;
- Flask-migrate:管理迁移数据库;
- Flask-Session:Session存储方式指定;
- Flask-WTF:表单;
- Flask-Mail:邮件;
- Flask-Bable:提供国际化和本地化支持,翻译;
- Flask-Login:认证用户状态;
- Flask-OpenID:认证;
- Flask-RESTful:开发REST API的工具;
- Flask-Bootstrap:集成前端Twitter Bootstrap框架;
- Flask-Moment:本地化日期和时间;
- Flask-Admin:简单而可扩展的管理接口的框架
安装:pip install flask
简单示例:
1 from flask import Flask
2
3 # 创建一个flask的应用程序,名字叫app
4 # flask对象的名字 = Flask(__name__)
5 # app可以随意起名字
6 # __name__:表示模块名
7
8 app = Flask(__name__)
9
10 """
11 通过装饰器,设置请求的路由
12 路由:就是一个url的地址,或者在java中也叫做接口
13 语法:@flask对象的名字.route("路径")
14 注意:app是对象的名字,名字可以随意取
15 @app.route('/aaa'):参数必须以/开头,否则会报错 ValueError: urls must start with a leading slash
16 def index():def表示定义一个函数,index是函数名字 函数名字随意取
17 """
18 @app.route('/')
19 def index():
20 """写我们的业务逻辑"""
21 # return表示展示页面,渲染页面,渲染就是展示的意思
22 return "我是第一个flask应用程序"
23
24
25 # 判断是否是入口
26 # 表示入口函数,固定语法
27 if __name__ == '__main__':
28 # 启动应用程序
29 app.run()
初始化参数介绍:
1 from flask import Flask
2
3 """
4 查看参数的快捷键:ctrl + p
5 static_path='xxx':静态路径,为了向下兼容,有些低版本使用的是这个
6 static_url_path='xxx':url路径.表示的也是静态路径,
7 表示的是一个意思,目的是为了向下兼容,表示静态文件
8 static_folder='static',表示静态文件夹,系统默认叫static,里面存放静态文件,比如图片等等
9 template_folder='teplates':模板文件夹,里面存放HTML文件
10 """
11 app = Flask(__name__, static_path=None, static_url_path=None, static_folder='static',template_folder='templates')
12
13
14 @app.route("/") # 千万注意:是/ 不是.是斜杠/
15 def index():
16 return "index page"
17
18
19 if __name__ == '__main__':
20 app.run()
21 """
22 lsof -i 5000:监听5000端口
23 kill -9 4728: 杀死5000端口的应用PID
24
25 PID是进程id
26
27 加载方式:
28 from_object 对象
29 from_pyfile 文件
30 from_envvar 环境变量
31 """
View Code
对象方式加载配置文件:
1 """
2 起名字不要用中文
3 """
4 from flask import Flask
5
6 app = Flask(__name__)
7
8
9 class Config(object):
10 """创建一个配置类,名字叫Config,名字随便取"""
11 # 开启调试模式,调试模式为True
12 # 自下而上找错误
13 # 加载配置文件的好处:可以看到具体的错误信息,自动定位到错误的位置
14 DEBUG = True
15 # 自定义参数,参数不可以小写.只能是大写
16 # 大小写切换快捷键:ctrl + shift +u
17 ITCAST = "python"
18
19
20 # flask程序 从对象加载配置文件,配置文件来自Config这个对象
21 app.config.from_object(Config)
22
23
24 @app.route("/")
25 def index():
26 # a = 1 / 0
27 # 如果是自定义的参数,就需要自己取
28 # 如果从对象中取自定义的值,必须从对象读取,不能从文件读取
29 print(app.config.get('ITCAST'))
30 return 'index page'
31
32
33 if __name__ == '__main__':
34 app.run()
View Code
文件方式加载配置文件:
注意:先要在同级目录下创建一个config.cfg文件
1 from flask import Flask
2
3 app = Flask(__name__)
4
5
6 class Config(object):
7 """创建一个配置类,名字叫Config,名字随便取"""
8 # 开启调试模式,调试模式为True
9 # 自下而上找错误
10 # 加载配置文件的好处:可以看到具体的错误信息,自动定位
11 DEBUG = True
12
13
14 # flask程序 从文件加载配置文件
15 # 从对象加载必须 掌握,文件加载也得会
16 # 从对象加载的参数里面传入的是对象
17 # 从文件加载的参数里面传入的是文件名,是字符串类型,有引号
18 app.config.from_pyfile("config.cfg")
19
20
21 @app.route("/")
22 def index():
23 a = 1 / 0
24 return 'index page'
25
26
27 if __name__ == '__main__':
28 app.run()
View Code
run()参数:
1 from flask import Flask
2
3 app = Flask(__name__)
4
5
6 @app.route('/')
7 def index():
8 a = 1/0
9 return 'index page'
10
11
12 if __name__ == '__main__':
13 """
14 修改ip地址:
15 第一个参数是ip地址,
16 第二个是端口号,
17 第三个是开启调试模式(和之前的DEBUG是一样的功能,
18 这里是系统为了方便写在这里的.开发的时候需要自己写)
19
20 一般不建议修改,就使用这个默认的值就好
21 """
22 app.run(host='192.168.14.27', port=9000, debug=True)
View Code
开启debug=True模式后,详细的报错信息就会展示在控制台.
路由系统:
- @app.route('/user/<username>')
- @app.route('/post/<int:post_id>')
- @app.route('/post/<float:post_id>')
- @app.route('/post/<path:path>')
- @app.route('/login', methods=['GET', 'POST'])
常用路由系统有以上五种,所有的路由系统都是基于下面的对应关系来处理:
1 #: the default converter mapping for the map.
2 DEFAULT_CONVERTERS = {
3 'default': UnicodeConverter,
4 'string': UnicodeConverter,
5 'any': AnyConverter,
6 'path': PathConverter,
7 'int': IntegerConverter,
8 'float': FloatConverter,
9 'uuid': UUIDConverter,
10 }
自定义转换器进行正则匹配:
1 """
2 之前只是限制数据类型,今天限制更多了.
3 限制位数,每一位的数据类型等
4 """
5 from flask import Flask
6
7 # routing 和路由相关的都在这里 第一步:
8 from werkzeug.routing import BaseConverter
9 """
10 转换器:converter
11 """
12
13 app = Flask(__name__)
14
15
16 # 需要自定义转换器,通过正则方式进行自定义转换器,
17 # alt+enter快捷键就是进行导包 第二步:继承
18 class RegBaseConverter(BaseConverter):
19 # 表示限制的数据类型是数字,并且只能是5位,regex不能随便取,只能是regex,父类中定义好了
20 regex = 'd{5}'
21
22
23 # app.url_map得到所有的url地址(也就是路由)
24 # converters 表示转换器
25 # 自定义转换器,那么需要给自定义转换器起一个名字.注意:自己取的名字不能和系统的重名
26 # 把我们自定义的转换器放到converters这个转换器的集合里面 第三步:添加到转换器字典中
27 app.url_map.converters['aaaaaa'] = RegBaseConverter
28
29
30 # 限制数据类型是整型,只能限制数据类型.不能限制参数的位数.不好用.
31 # <aaaaaa:index_id>:进行替换,aaaaaa在这里就代表上面的正则表达式 第四步:使用
32 @app.route('/index/<aaaaaa:index_id>')
33 def index(index_id):
34 return 'index=%s' % index_id
35
36
37 if __name__ == '__main__':
38 app.run()
39 """
40 DEFAULT_CONVERTERS = {
41 'default': UnicodeConverter,
42 'string': UnicodeConverter,
43 'any': AnyConverter,
44 'path': PathConverter,
45 'int': IntegerConverter,
46 'float': FloatConverter,
47 'uuid': UUIDConverter,
48 }
49
50 一共6种转换器,前面两种是一样的.默认的是接收所有的和字符型一样
51 """
View Code
更专业的解答:https://segmentfault.com/q/1010000000125259
模板:
1、模板的使用
Flask使用的是Jinja2模板,所以其语法和Django无差别
2、自定义模板方法
Flask中自定义模板方法的方式和Bottle相似,创建一个函数并通过参数的形式传入render_template,如:
1 <!DOCTYPE html>
2 <html lang="en">
3 <head>
4 <meta charset="UTF-8">
5 <title>模板</title>
6 </head>
7 <body>
8 <h1>获取到后台传来的数据:</h1>
9 {# {{ 变量名 }} 表示模板文件的语法,用来获取后端传来的变量 #}
10 {# 变量.键 的方式获取键对应的值 只要是字典格式的数据,获取key对应的value
11 都是采用对象/变量 .key的方式
12 #}
13 {#使用p标签之后,输出显示就是一行一行的显示#}
14 <p>名字:{{ data_obj.name }}</p>
15 <p>年龄{{ data_obj.age }}</p>
16 <p>地址:{{ data_obj.address }}</p>
17 <p>列表数据:{{ data_obj.my_list }}</p>
18 <p>字典中的城市数据:{{ data_obj.my_dict.city }}</p>
19 </body>
20 </html>
对应的后台.py文件:
1 from flask import Flask, render_template
2
3 app = Flask(__name__)
4
5 """
6 模板传递数据:
7 注意:
8 模板其实是一个包含响应文本的文件.
9 本质就是一个响应的文件.记住:是文件,文件
10 误区:模板就是HTML.
11
12 作用:
13 1.降低耦合度,更好的控制代码
14 """
15
16
17 @app.route('/login')
18 def index():
19 # 业务逻辑已实现
20 # 处理用户名,密码
21 data = {
22 'name': 'libin',
23 'age': 56,
24 'address': 'USA',
25 'my_list': [1, 2, '45'],
26 'my_dict': {'city': 'sz'}
27 }
28 # 第一个参数是模板文件的名字,
29 # 第二个参数是需要传递到文件上面的数据,前面参数是占位符,后面的是变量的名字
30 return render_template('demo1.html', data_obj=data)
31
32
33 if __name__ == '__main__':
34 app.run()
View Code
公共组件:
1、请求
对于Http请求,Flask会讲请求信息封装在request中(werkzeug.wrappers.BaseRequest),提供的如下常用方法和字段以供使用:
1 request.method
2 request.args
3 request.form
4 request.values
5 request.files
6 request.cookies
7 request.headers
8 request.path
9 request.full_path
10 request.script_root
11 request.url
12 request.base_url
13 request.url_root
14 request.host_url
15 request.host
常用的介绍:

args参数:
1 # ------------------------------args参数-------------------
2 """
3 args:就是get请求时url后面加?的后面的数据
4 """
5 from flask import Flask, request
6
7 app = Flask(__name__)
8
9
10 @app.route('/index', methods=['GET', 'POST'])
11 def index():
12 # ?号后面的数据
13 # request.args :获取到?后面的数据
14 city = request.args.get('city')
15 print(city)
16 return 'index'
17
18
19 if __name__ == '__main__':
20 app.run()
form表单数据:
1 """
2 request获取数据
3 """
4 # -------------------form表单-------------------------
5 from flask import Flask, request
6
7 app = Flask(__name__)
8
9
10 @app.route('/index', methods=['GET', 'POST'])
11 def index():
12 print('前端请求的url地址:', request.url)
13 """所有的请求数据都是封装在request里面"""
14 # request.form:获取到表单数据
15 # request.form.get():获取到表单里面具体的某一个数据
16 name = request.form.get('name')
17 pwd = request.form.get('pwd')
18 return 'name=%s,pwd=%s' % (name, pwd)
19
20
21 if __name__ == '__main__':
22 app.run()
files多媒体数据:
1 # -----------------------files多媒体-------------------
2 from flask import Flask, request
3
4 app = Flask(__name__)
5
6
7 # 上传图片,只能选POST方式
8 @app.route('/', methods=['POST'])
9 def index():
10 # request.files 获取多媒体数据,比如拿到图片
11 pic = request.files.get('pic')
12 # pic.save('./bb.png') :保存图片,上传图片
13 pic.save('./bb.png')
14 return '上传成功!'
15
16
17 if __name__ == '__main__':
18 app.run()
返回JSON格式数据:
from flask import Flask, jsonify
app = Flask(__name__)
# -------------------就是返回给客户端呈现的数据是json格式的-----------
@app.route('/')
def index():
data = {
"name": "python",
"age": 29
}
# -------------jsonify方式-------------------------------------------
return jsonify(data)
if __name__ == '__main__':
app.run()
原生方式返回JSON:
# ------------------------原生方式:json.dumps()----------------------------
from flask import Flask
import json
app = Flask(__name__)
@app.route('/')
def index():
data = {
"name": "python",
"age": 29
}
# -------------原生方式json.dumps()--------
# 直接返回报错,需要进行包装一下,告诉系统这是个json数据.python默认会识别为字典
# json.dumps()字典数据转成json数据
res = json.dumps(data)
# 第一个参数表示内容,第二个参数表示状态码,第三个表示数据类型
return res, 200, {'Content-Type': 'application/json'}
if __name__ == '__main__':
app.run()
重定向:
1 """
2 重定向:请求页面的时候,请求页面不存在,返回的是另外一个页面.
3 一般在双11的活动的时候,活动页面...
4 京东原来的域名www.360.buy.com,如果访问原来的就需要跳转到现在的域名www.jd.com
5
6 """
7 from flask import Flask, redirect, url_for # redirect, url_for 这两个是重定向模块
8
9 app = Flask(__name__)
10
11
12 @app.route('/360buy')
13 def index():
14 # redirect 重定向
15 """
16 17 url_for会根据传入的路由函数名,返回该路由对应的URL,在模板中始终使用url_for()就可以安全的修改路由绑定的URL,则不必担心模板中渲染url链接出错:
18 19 """
20 return redirect(url_for('jd'))
21
22
23 @app.route('/jd')
24 def jd():
25 return '进入到京东商城页面'
26
27
28 if __name__ == '__main__':
29 app.run()
自定义状态码:
1 from flask import Flask
2
3 app = Flask(__name__)
4
5 """
6 自定义状态码:
7 使用场景:
8 错误代码的对照表.可以自己定义相关的错误.比如实际开发中的具体错误:10004表示注册成功后未登录等等
9
10 在交互成功之后要求交互成功的内容再具体一点,是交互的哪些内容成功?
11 """
12
13
14 @app.route('/')
15 def index():
16 # 999 是请求状态码,是自定义的状态码
17 return 'index', 999 # 返回客户端给用户看的,999表示...错误
18
19
20 if __name__ == '__main__':
21 app.run()
abort异常捕获:
1 """
2 abort的作用:
3 1.捕获HTTP的异常(之前是try...exception抓取),这里flask重新进行了封装.
4 2.终止程序
5 3.抛出异常
6
7 细节-注意:在abort(500)函数中和@app.errorhandler(500)中,
8 参数必须是http协议标准的状态码.
9
10 abort(状态码)和@app.errorhandler(状态码)中的参数都是状态码,这两个状态码必须一致.即这两个参数必须一致.
11
12 abort(参数1)和@app.errorhandler(参数2):注意,参数1和参数2必须一致
13
14
15 在开发中实际应用:
16 1.一般用来展示404的页面(资源没找到,请求页面不存在)
17
18 19 """
20 from flask import Flask, abort
21
22 app = Flask(__name__)
23
24
25 @app.route('/')
26 def index():
27 name = ''
28 pwd = ''
29
30 if name != 'admin' and pwd != '123':
31 print('进入了函数')
32 # 把程序终止掉,后面的业务逻辑就不需要执行了,因为即使执行也没有实际意义
33 abort(500)
34 # 进入到数据库,进行数据库查询
35 print('看看我进入数据库了没')
36 return 'index page'
37
38
39 @app.errorhandler(500) # 抛出捕获到的异常信息
40 def error_500_handler(error):
41 # return '程序报错了:%s' % error
42 return '替换为一个html页面'
43
44
45 if __name__ == '__main__':
46 app.run()
内置过滤器filter:
1 from flask import Flask, render_template
2
3 app = Flask(__name__)
4
5 """
6 过滤器本质就是一个函数.
7 作用:
8 1.不仅仅只是输出值
9 2.还希望更改值
10
11 """
12
13
14 @app.route('/')
15 def index():
16 return render_template('demo2.html')
17
18
19 if __name__ == '__main__':
20 app.run()
对应的HTML:
1 <!DOCTYPE html>
2 <html lang="en">
3 <head>
4 <meta charset="UTF-8">
5 <title>过滤器</title>
6 </head>
7 <body>
8 <h1>过滤器的使用</h1>
9 {#{{ 需要修改的值|过滤器的名字 }}#}
10 {# capitalize: 首字母大写#}
11 <p>首字母大写:{{ 'hello'|capitalize }}</p>
12 {# 模板中处于安全考虑,默认情况下,会把标签进行转义,即把<>这个转成 <> #}
13 {# 但是在 开发中,我们有时候需要使用标签展示 ,需要禁止转义 #}
14 <p>禁止转义:{{ '<h1>黑马程序员</h1>'|safe }}</p>
15 <p>单词大写:{{ 'hello'|upper }}</p>
16 <p>单词小写:{{ 'HELLO'|lower }}</p>
17 <p>单词反转:{{ 'hello'|reverse }}</p>
18 <p>每个单词的首字母大写:{{ 'hello world!'|title }}</p>
19 <hr>
20
21 <h1>列表操作:</h1>
22 <p>获取列表中的第一个元素:{{ [1,2,3,4,5,6]|first }}</p>
23 <p>获取列表中的最后一个元素:{{ [1,2,3,4,5,6]|last }}</p>
24 <p>列表求和:{{ [1,2,3,4,5,6]|sum }}</p>
25 <p>列表排序:{{ [11,21,3,4,5,6]|sort }}</p>
26 <hr>
27
28
29
30 </body>
31 </html>
自定义过滤器:
1 from flask import Flask, render_template
2
3 app = Flask(__name__)
4
5 """
6 过滤器本质就是一个函数.
7 内置的无法满足需求
8 自定义过滤器实际上就是写自定义函数
9
10 app.add_template_filter(do_setup2, 'xx'):
11 1.先定义一个函数
12 2.添加函数名do_setup2到flask的app对象里面,把过滤器函数名字'xx'传给模板文件
13 3.在模板文件中取出过滤器函数名字 'xx'
14
15 注意:在模板中只是使用过滤器,并不能自定义过滤器,自定义是在.py文件中进行
16 """
17
18
19 # pycharm原生格式化代码:ctrl + alt + l
20 # 目前自己使用的:shift + alt + f
21
22 @app.route('/')
23 def index():
24 return render_template('demo3.html')
25
26
27 # 自定义filter,每隔一个切割一次
28 def do_setup2(my_list):
29 # my_list是前端传来的数据 [11,21,3,4,5,6,9]
30 return my_list[::2]
31
32
33 # 在模板里面添加一个过滤器
34 # 第一个参数:表示自定义函数的名字,
35 # 第二个参数:表示在模板里面使用的过滤器的名字
36 app.add_template_filter(do_setup2, 'xx')
37
38 if __name__ == '__main__':
39 app.run()
对应的HTML:
1 <!DOCTYPE html>
2 <html lang="en">
3 <head>
4 <meta charset="UTF-8">
5 <title>自定义filter</title>
6 </head>
7 <body>
8 {#{{ xx:自定义 }}#}
9 <p>对列表进行切片:{{ [11,21,3,4,5,6,9]|xx }}</p>
10 </body>
11 </html>
控制代码块:
1 from flask import Flask, render_template
2
3 app = Flask(__name__)
4
5 """
6 控制代码块主要包含两个:
7 - if/else if /else / endif
8 - for / endfor
9 """
10
11
12 @app.route('/')
13 def index():
14 my_list = [
15 {
16 "id": 1,
17 "value": "我爱工作"
18 },
19 {
20 "id": 2,
21 "value": "工作使人快乐"
22 },
23 {
24 "id": 3,
25 "value": "沉迷于工作无法自拔"
26 },
27 {
28 "id": 4,
29 "value": "日渐消瘦"
30 },
31 {
32 "id": 5,
33 "value": "以梦为马,越骑越傻"
34 }
35 ]
36 return render_template('demo4.html', my_list=my_list)
37
38
39 if __name__ == '__main__':
40 app.run(debug=True)
对应的HTML:
1 <!DOCTYPE html>
2 <html lang="en">
3 <head>
4 <meta charset="UTF-8">
5 <title>控制代码块</title>
6 </head>
7 <body>
8 <h1>控制语句</h1>
9 {# 专门给for循环使用 loop.....#}
10 {% for item in my_list %}
11 {% if loop.index==1 %}
12 <li style="background-color: deeppink">{{ item.value }}</li>
13 {% elif loop.index==2 %}
14 <li style="background-color:greenyellow">{{ item.value }}</li>
15 {# 注意: else loop.index==3 这样是错误的写法,jinja2模板语法会报错: jinja2.exceptions.TemplateSyntaxError: expected token 'end of statement block', got 'loop'
16 正确写法: {% else %} else就是表示最后一个了,不再需要加loop.index进行判断
17 #}
18 {% else %}
19 <li style="background-color:red">{{ item.value }}</li>
20 {% endif %}
21 {% endfor %}
22
23
24 </body>
25 </html>


发送消息flash:
1 from flask import Flask, flash, render_template
2
3 """
4 flash:作用:表示发送消息,往队列里面发送
5 flash是闪电的意思
6
7 类似前端里面的提示消息
8
9 使用场景:
10 在页面需要展示后端发送过来的消息的时候,进行使用,提示用户
11
12
13 扩展:
14 1.因为在发送消息的时候使用session,会存储一些隐私数据,比如购物车,为了安全起见,
15 在flask中如果使用到session,都必须加密,使用secret_key进行加密
16 """
17
18 app = Flask(__name__)
19
20 # 加密口令,config['SECRET_KEY'] 注意:config里面的key必须大写
21 # ['SECRET_KEY'] 必须遵循config配置文件中默认的写法
22 # RuntimeError: the session is unavailable because no secret key was set.
23 # Set the secret_key on the application to something unique and secret.
24 # 设置秘钥不能为空,否则报错
25 # app.config['SECRET_KEY'] = ''
26 # 专业术语叫salt加盐
27 app.config['SECRET_KEY'] = 'shdfsjk'
28
29 # 加密之后再加密,再加密,至少十几次。银行密码6位数字的情况下。
30 # 专业术语叫做:加盐salt 加密
31 """
32 常用的加密算法:MD5,SHA1,BASE64等等
33 注意:MD5是不可逆的,即MD5加密之后,不会反向破解出来
34
35 撞库:
36
37 """
38
39
40 @app.route('/')
41 def index():
42 # 内置对象,不需要传递
43 flash("用户名不正确")
44 flash("用户名不正确")
45 flash("用户名不正确")
46 flash("用户名不正确")
47 return render_template('demo6.html')
48
49
50 if __name__ == '__main__':
51 app.run(debug=True)
对应的HTML:
1 <!DOCTYPE html>
2 <html lang="en">
3 <head>
4 <meta charset="UTF-8">
5 <title>Title</title>
6 </head>
7 <body>
8 {# get_flashed_messages 这是一个函数地址,加()才是一个函数,返回值是flashes
9
10 具体作用:Pulls all flashed messages from the session and returns them.
11 #}
12 {% for msg in get_flashed_messages() %}
13 <p>{{ msg }}</p>
14 {% endfor %}
15
16 </body>
17 </html>
message消息:
1 from flask import Flask, flash,render_template, request, get_flashed_messages
2
3 """
4 get_flashed_messages():
5
6 message是一个基于Session实现的用于保存数据的集合,其特点是:使用一次就删除
7 用来存放临时值
8 """
9 app = Flask(__name__)
10 app.secret_key = 'some_secret'
11
12
13 @app.route('/')
14 def index1():
15 # 12.获取消息
16 v = get_flashed_messages()
17 print(v)
18 return render_template('index1.html')
19
20
21 # 设置完之后,只能通过浏览器访问一次刚刚设置的值,访问完之后就不能再第二次访问了
22 @app.route('/set')
23 def index2():
24 v = request.args.get('p')
25 # 设置设置消息
26 flash(v)
27 return 'ok'
28
29
30 if __name__ == "__main__":
31 app.run()
对应的HTML:
1 <!DOCTYPE html>
2 <html>
3 <head lang="en">
4 <meta charset="UTF-8">
5 <title></title>
6 </head>
7 <body>
8 <h1>这是index1页面</h1>
9 {% with messages = get_flashed_messages() %}
10 {% if messages %}
11 <ul class=flashes>
12 {% for message in messages %}
13 <li>{{ message }}</li>
14 {% endfor %}
15 </ul>
16 {% endif %}
17 {% endwith %}
18 </body>
19 </html>
模板继承:
1 from flask import Flask,render_template
2
3 """
4 模板继承:复用
5
6 如果子类需要继承父类,就在父类加一个block
7
8 {% block content %}
9
10 {% endblock %}
11
12
13 子类需要继承父类:
14
15 {% block content %}
16 <h1>子类的内容</h1>
17 {% endblock %}
18
19
20 需要注意:block里面的内容,子类和父类必须保证一样,用来识别是哪一个内容被修改
21
22
23
24 在子类中写{% extends "demo8_father.html" %},
25 如果子类和父类数据不一样,添加block ...
26 """
27
28 app = Flask(__name__)
29
30
31 @app.route('/')
32 def index():
33 return render_template('demo7_son.html')
34
35
36 if __name__ == '__main__':
37 app.run()
对应的HTML:
demo7_son:
1 {% extends "demo8_father.html" %}
2
3 {% block content %}
4 <h1>子类的内容页面</h1>
5 {% endblock %}
demo8_father:
1 <!DOCTYPE html>
2 <html lang="en">
3 <head>
4 <meta charset="UTF-8">
5 <title>Title</title>
6 </head>
7 <body>
8 <h1>父类的顶部</h1>
9
10 {% block content %}
11 <h1>父类的内容</h1>
12 {% endblock %}
13
14 <h1>父类的底部</h1>
15 </body>
16 </html>
命令行方式执行程序:
1 from flask import Flask
2 from flask_script import Manager
3
4 # Manager可以用来管理我们的应用程序
5 app = Flask(__name__)
6 # 创建一个flask的脚本,传输一个flask对象,把app对象交给manager管理 注意:需要传参数app
7 manager = Manager(app)
8 """
9 因为公司里面都是脚本命令行操作
10 """
11
12
13 @app.route('/')
14 def index():
15 # index是视图函数
16 return 'index'
17
18
19 if __name__ == '__main__':
20 manager.run()
21
内置对象:
1 from flask import Flask, render_template, g, url_for
2
3 app = Flask(__name__)
4
5 """
6 g变量就是一个容器,内置对象,不需要手动传
7
8 内置对象:
9 作用:如果使用内置对象,就不需要手动传递值,直接在页面上面使用即可
10 只是为了方便取值.
11 因为在模板页面里面已经把这些变量定义好了
12
13 g表示一个容器,里面可以存储值
14 格式: g.变量名 其中变量名可以随便取
15 """
16
17
18 @app.route('/')
19 def index():
20 g.name = 'heima'
21 return render_template('demo5.html')
22
23
24 if __name__ == '__main__':
25 app.run()
对应的HTML:
1 <!DOCTYPE html>
2 <html lang="en">
3 <head>
4 <meta charset="UTF-8">
5 <title>Title</title>
6 </head>
7 <body>
8 <h1>特有内置对象</h1>
9 <p>获取内置的debug对象:{{ config.DEBUG }}</p>
10 <p>获取内置的请求的url:{{ request.url }}</p>
11 <p>获取内置的url_for对象:{{ url_for.url }}</p>
12 <p>获取内置的g变量里面的数据:{{ g.name }}</p>
13 </body>
14 </html>
内置的config默认信息:
