重定向,顾名思义,就是重新定向到一个新的位置,比如我们在浏览器的页面自动跳转到了另一个页面,又比如访问了一个页面,然后观察网址之后并不是我们输入的网址,这个过程就是重定向完成的。
|
http状态码 |
应用场景 |
优势 |
暂时性重定向 |
302 |
访问一些需要权限的页面,会自动重定向到权限认证的页面 |
重定向在设计上会提升用户体验 |
永久性重定向 |
301 |
废弃原有的网址被访问,会自动重定向到新的网址确保用户访问成功 |
重定向在设计上会提升用户体验,有利于搜索引擎优化 |
例1:访问淘宝的时候,你选择了已经购买的商品,但是你并没有登录过淘宝,那么这个时候如果只是提示 “请登录再访问!”,那么相信这种设计是留不住用户的,不如直接为用户重定向到登录页面。
例2:比如想废弃原本的网址,那么用户并不知道这个事情,所以用户还是会访问原来的网址,那么就会内部做一个重定向到新启用的网址,重定向的过程会有状态码的返回,搜索引擎捕捉到重定向的代码,有利于搜索引擎优化。
关键词:重定向在设计上会提升用户体验 ,有利于搜索引擎优化
首先从flask
模块中把导入redirect
| from flask import Flask,redirect |
| from flask import Flask,redirect |
| ... |
| @app.route('/user_info/') |
| def user_info(): |
| name = request.args.get('name') |
| pwd = request.args.get('pwd') |
| if name=='mark' and pwd == '123': |
| return '{}的信息'.format(name) |
| return redirect('/login/') |
| |
| @app.route('/login/') |
| def login(): |
| return '这是登录页面' |
| ... |
没有通过权限验证的情况
通过权限验证的情况
关键词:暂时性重定向return redirect('/login/')
即可实现重定向
| from flask import Flask,redirect |
| ... |
| @app.route('/user_info/') |
| def user_info(): |
| name = request.args.get('name') |
| pwd = request.args.get('pwd') |
| if name=='mark' and pwd == '123': |
| return '{}的信息'.format(name) |
| return redirect('/login/', code=301) |
| |
| @app.route('/login/') |
| def login(): |
| return '这是登录页面' |
| ... |
关键词:永久性重定向只给redirect('/login/', code=301)
多加了个code=301
参数
实现视图的业务逻辑和返回给前端的页面逻辑分离的工具,我们称之为模板引擎。
什么是模板?
模板可以理解为一个特殊的html
文件,特殊之处就在于这个html
文件包含固定内容和动态部分,其动态部分可以借助模板引擎进行传参
在上一章其实我们已经应用过模板引擎,试想一下如果没有模板引擎,直接给把模板的html代码写在视图函数里面,会给程序员的日常开发带来了多大的困扰,模板引擎帮我们分开了业务逻辑和页面逻辑,并且我们每次修改一个大字符串会非常不方便。模板引擎还可以读取并执行模板中的特殊语法标记,并根据传入的数据将变量替换为实际值,然后返回给浏览器,这个过程我们称之为渲染。
关键字:完成了业务逻辑和页面逻辑的分离,实现了动态的去渲染页面。
Flask
使用jinja2
作为框架的默认模板引擎,Jinja2
是基于python
的模板引擎,功能比较类似于于PHP
的smarty
,J2ee
的Freemarker
和velocity
。Jinja2
除了设置变量,还允许我们在模板中添加if判断,执行for迭代,调用函数等,以各种方式控制模板的输出。并且jinja2
不限制模板的格式为html
,可以是任何格式的文本文件。
项目目录
项目代码
(1)login01.html
| <!DOCTYPE html> |
| <html lang="en"> |
| <head> |
| <meta charset="UTF-8"> |
| <title>登录界面</title> |
| </head> |
| <body> |
| <h1>login01</h1> |
| <form action="" method="POST"> |
| 用户:<input type="text" name="username"> |
| 密码:<input type="text" name="password"> |
| <input type="submit" value="提交"> |
| </form> |
| </body> |
| </html> |
(2)login02.html
| <!DOCTYPE html> |
| <html lang="en"> |
| <head> |
| <meta charset="UTF-8"> |
| <title>登录界面</title> |
| </head> |
| <body> |
| <h1>login01</h1> |
| <form action="" method="POST"> |
| 用户:<input type="text" name="username"> |
| 密码:<input type="text" name="password"> |
| <input type="submit" value="提交"> |
| </form> |
| </body> |
| </html> |
(3) server.py
| from flask import Flask, render_template |
| import config |
| |
| app = Flask(__name__) |
| app.config.from_object(config) |
| |
| @app.route('/demo/') |
| def demo(): |
| return '<h2>手写html</h2>' |
| |
| @app.route('/demo02/') |
| def demo02(): |
| return '''<!DOCTYPE html> |
| <html lang="en"> |
| <head> |
| <meta charset="UTF-8"> |
| <title>登录界面</title> |
| </head> |
| <body> |
| <!--<form action="/login_request/" method="POST">--> |
| <form action="" method="POST"> |
| 用户:<input type="text" name="username"> |
| 密码:<input type="text" name="password"> |
| <input type="submit" value="提交"> |
| </form> |
| </body> |
| </html>''' |
| |
| @app.route('/demo03/') |
| def demo03(): |
| return render_template('login01.html') |
| |
| @app.route('/demo04/') |
| def demo04(): |
| return render_template('box/login02.html') |
| |
| if __name__ == '__main__': |
| app.run() |
server.py代码逻辑分析:
-
demo函数 和 demo02函数证明直接返回html代码可渲染浏览器
-
demo03 证明利用模板引擎 实现了业务逻辑和页面逻辑的分离,减轻了开发的复杂度
-
demo04 证明了 render_template('box/login02.html')
的路径是templates文件夹的相对路径
Flask类中的template_folder
参数可以指定模板寻找路径
基于上2.3.1的项目
- 现在把templates中的文件复制到
C:/Users/Administrator/Desktop/template_box
中,并且删除项目中的templates的文件。
- 修改server.py中
app = Flask(__name__)
为app = Flask(__name__,template_folder='C:/Users/Administrator/Desktop/template_box')
分析:
渲染一切正常 说明Flask类中的template_folder
参数可以指定模板寻找路径。
我们之前提到过,模板引擎还可以读取并执行模板中的特殊语法标记,并根据传入的数据将变量替换为实际值,这个步骤我们就称之为模板引擎传参。
我们传参的时候要应用render_template()
利用render_template的第二个参数进行传参,该函数在定义时候,第二个参数是可变长形参,所以在传值的时候我们可以传入多个关键字实参。
在模板中接收的时候使用{{}}
包裹参数进行接收。
目录结构
| │ server.py |
| │ |
| └─templates |
| index.html |
server.py
| @app.route('/') |
| def index(): |
| |
| return render_template('index.html',name="mark",age=18) |
index.html
| <!DOCTYPE html> |
| <html lang="en"> |
| <head> |
| <meta charset="UTF-8"> |
| <title>模板传参</title> |
| </head> |
| <body> |
| {{name}} |
| {{age}} |
| </body> |
| </html> |
目录结构:同上
server.py
| @app.route('/demo1/') |
| def demo1(): |
| context_dict = {"name":"mark", |
| "age":"mark", |
| "sex":"girl"} |
| |
| return render_template('index.html',context_dict = context_dict) |
index.html
| <!DOCTYPE html> |
| <html lang="en"> |
| <head> |
| <meta charset="UTF-8"> |
| <title>模板传参</title> |
| </head> |
| <body> |
| {{context_dict.name}} |
| {{context_dict.age}} |
| {{context_dict.sex}} |
| </body> |
| </html> |
目录结构:同上
server.py
| def demo2(): |
| context_dict = {"name": "mark", |
| "age": "mark", |
| "sex": "girl", |
| "other_info":{"tel":1365, |
| "qq":565656}} |
| |
| return render_template('index.html',**context_dict) |
index.html
| <!DOCTYPE html> |
| <html lang="en"> |
| <head> |
| <meta charset="UTF-8"> |
| <title>模板传参</title> |
| </head> |
| <body> |
| {{name}} |
| {{age}} |
| {{sex}} |
| {{other_info.tel}} |
| {{other_info["qq"]}} |
| </body> |
| </html> |
在视图函数中
- render_template传参的时候以关键字实参进行传参。可以传多个,可以用**讲字典打散成关键字实参。
在模板中
在模板中如果有使用url的需求,我们可以直接手写一个url,也可以使用{{ url_for('视图函数名') }
动态翻转一个url。
项目目录:
| │ server.py |
| │ |
| └─templates # 文件夹 |
| index.html |
| info.html |
server.py
| ... |
| @app.route('/') |
| def index(): |
| |
| return render_template('index.html', name="mark", age=18) |
| |
| @app.route('/info/') |
| def info(): |
| |
| return render_template('info.html') |
| ... |
info.html
| <!DOCTYPE html> |
| <html lang="en"> |
| <head> |
| <meta charset="UTF-8"> |
| <title>信息页面</title> |
| </head> |
| <body> |
| <h1>这是信息页面</h1> |
| </body> |
| </html> |
index.html
| <!DOCTYPE html> |
| <html lang="en"> |
| <head> |
| <meta charset="UTF-8"> |
| <title>模板传参</title> |
| </head> |
| <body> |
| <a href="/info/">正常跳转</a> |
| <a href="{{ url_for('info') }}">urlfor跳转</a> |
| </body> |
| </html> |
正常跳转 和 urlfor跳转,皆可以实现跳转到info.html页面。
正常跳转就不做演示了
- url_for 在视图函数中如何使用,在模板中同样的用法。
- 支持翻转查询字符串
- 支持动态路由翻转
在jinja2中用{% %}
特殊符号来编辑控制语句,一个语句以{% ... %}
为起始 并且以{% end... %}
来标记结束。
可以使用> , < , <=, ==,!=,
进行判断,
也可以使用 and,or,not,()
来进行逻辑合并
| {% if age > 18 %} |
| <p>成年人</p> |
| {% elif age == 18 %} |
| <p>刚刚成年</p> |
| {% else %} |
| <p>未成年</p> |
| {% endif %} |
注意:<p>
只是为了渲染明显
项目目录:
| │ server.py |
| │ |
| └─templates # 文件夹 |
| index.html |
server.py
| ... |
| @app.route('/') |
| def hello_world(): |
| context_dict = { |
| 'age': 17, |
| 'sex': 'man', |
| } |
| return render_template('index.html',**context_dict) |
| ... |
index.html
| <!DOCTYPE html> |
| <html lang="en"> |
| <head> |
| <meta charset="UTF-8"> |
| <title>jinja2分支</title> |
| </head> |
| <body> |
| {% if sex == 'man' %} |
| <p>男人</p> |
| {% else %} |
| <p>女人</p> |
| {% endif %} |
| |
| {% if age > 18 %} |
| <p>成年人</p> |
| {% elif age == 18 %} |
| <p>刚刚成年</p> |
| {% else %} |
| <p>未成年</p> |
| {% endif %} |
| </body> |
| </html> |
for
循环可以便利任何一个可迭代对象,包括列表、字典等,支持反向遍历
列表循环:
| {% for country in countrys%} |
| <p>{{ country }}</p> |
| {% else %} |
| <p>没有值</p> |
| {% endfor %} |
项目目录:
| │ server.py |
| │ |
| └─templates # 文件夹 |
| index.html |
sever.py
| @app.route('/') |
| def hello_world(): |
| context_dict = { |
| 'countrys':["1-china","2-America","3-French"] |
| } |
| return render_template('index.html',**context_dict) |
index.html
| <!DOCTYPE html> |
| <html lang="en"> |
| <head> |
| <meta charset="UTF-8"> |
| <title>for循环</title> |
| </head> |
| <body> |
| {% for country in countrys %} {# {% for country in countrys|reverse %} 可以实现反向遍历#} |
| <p>{{ country }}</p> |
| {% else %} |
| <p>没有值</p> |
| {% endfor %} |
| |
| </body> |
| </html> |
反向遍历实例
server.py
的 {% for country in countrys %}
改为 {% for country in countrys|reverse %}
可以实现反向遍历,运行效果如下图
项目目录
| │ server.py |
| │ |
| └─templates |
| index.html |
sever.py
| @app.route('/') |
| def hello_world(): |
| context_dict = { |
| 'countrys':["1-china","2-America","3-French"] |
| } |
| return render_template('index.html',**context_dict) |
| |
| @app.route('/demo/') |
| def demo(): |
| context_dict ={ |
| 'colleges':[ |
| { |
| 'name': '清华大学', |
| 'area': '北京' |
| }, |
| { |
| 'name': '复旦大学', |
| 'area': '上海' |
| '' |
| }, |
| { |
| 'name': '吉林大学', |
| 'area': '吉林' |
| }, |
| { |
| |
| 'name': '中山大学', |
| 'area': '广东' |
| } |
| ] |
| } |
| return render_template('index.html',**context_dict) |
index.html
| <!DOCTYPE html> |
| <html lang="en"> |
| <head> |
| <meta charset="UTF-8"> |
| <title>for循环</title> |
| </head> |
| <body> |
| |
| <table> |
| <tr> |
| <th>1开始的序号</th> |
| <th>0开始的序号</th> |
| <th>大学名称</th> |
| <th>所属地区</th> |
| <th>总数</th> |
| |
| </tr> |
| {% for college in colleges %} |
| {% if loop.first %} |
| <tr style="background: blue"> |
| {% elif loop.last %} |
| <tr style="background: yellow "> |
| {% else %} |
| <tr> |
| {% endif %} |
| <td>{{ loop.index }}</td> |
| <td>{{ loop.index0 }}</td> |
| <td>{{ college.name }}</td> |
| <td>{{ college.area }}</td> |
| <td>{{ loop.length }}</td> |
| </tr> |
| {% endfor %} |
| </table> |
| |
| </body> |
| </html> |
for循环常用变量表
for循环常用变量 |
功能描述 |
loop.index |
当前循环的索引(从1开始) |
loop.index0 |
当前循环的索引(从0开始) |
loop.first |
是否是第一次循环,是返回True,否则返回Flase |
loop.last |
是否是最后一次循环,是返回True,否则返回Flase |
loop.length |
总共可以循环的次数 / 迭代器的长度 |
for还可以else分支语法,如果for内部没有遍历出来内容,那么就会走else分支,反之如果for循环遍历出了内容,则不会运行else分支。
注意:jinja2
中的for
和 else
逻辑不通于python
在此不要类比python中的 for
和 else
。
| {% for country in countrys|reverse %} |
| <p>{{ country }}</p> |
| {% else %} |
| <p>没有值</p> |
| {% endfor %} |
在模板中加载静态文件的时候也要使用到url_for()
函数,去寻找具体的静态文件资源。第一个参数是定位到static
文件夹,filename
参数定位到static文件夹内的具体资源。
| {{ url_for('static',filename='相对于static文件夹的路径') }} |
项目目录:
| │ app.py |
| │ |
| ├─static |
| │ ├─css |
| │ │ demo.css |
| │ │ |
| │ ├─images |
| │ │ 1.png |
| │ │ |
| │ └─js |
| │ demo.js |
| │ |
| ├─templates |
| index.html |
app.py
| ... |
| |
| @app.route('/') |
| def hello_world(): |
| return render_template('index.html') |
| ... |
index.html
| <!DOCTYPE html> |
| <html lang="en"> |
| <head> |
| <meta charset="UTF-8"> |
| <title>静态文件加载</title> |
| |
| <link rel="stylesheet" href="{{ url_for('static',filename='css/demo.css') }}"> |
| <script src="{{ url_for('static',filename='js/demo.js') }}"></script> |
| |
| </head> |
| <body> |
| <img src="{{ url_for('static',filename='images/1.png') }}"> |
| </body> |
| </html> |
demo.css
demo.js
jinja2的模板继承可以把一些公共的代码定义到一个基模板中,比如把导航栏、页脚等通用内容放在基模板中,以后所有的子模板直接继承基模板,在子模板被渲染时会自动包含继承基模板的内容,通过模板的继承可以避免在多个模板中编写重复的代码。
在基模板中定义一些公共的代码,子模板会继承这些公共的代码,但是子模板需要根据自己的需求去实现不同的代码,这个时候就需要在基模板中提供一些接口,以便子模板实现自己的业务需求。
1 基本写法
在基/父模板中定义接口(block)
| {% block main %} {# main是自定义的变量名 #} |
| |
| {% endblock %} |
在子模板中继承父模板,并且重写接口(block)
| {% extends 'base.html' %} {# extends 后面跟的参数是导入的基模板相对于templates的路径 #} |
| {% block main %} |
| |
| {% endblock %} |
2 子模板中调用父模板代码block中的代码
基模板中
| {% block main %} |
| <p>父模板中main中原有的内容</p> |
| |
| {% endblock %} |
子模板中:
| {% block main %} |
| {{ super() }} {# 保留基模板中本块的代码 #} |
| <p>子模板中重写main的内容 </p> |
| {% endblock %} |
3 在子模板中调用其他block中的代码:
子模板中:
| {% block main %} |
| {{ self.demo() }} {# self.其他block名字 #} |
| <p>子模板中重写main的内容 </p> |
| {% endblock %} |
4 子模板中的想定义自己的代码只能放到block中,否则无效
注意:这里面我们使用了bootstrap框架。
bootstrap3的中文官网:https://v3.bootcss.com/
1 首先下载 用于生产环境的 Bootstrap
2 解压出来里面的css文件
项目目录
| │ app.py |
| │ |
| ├─static |
| │ └─css |
| │ bootstrap-theme.css |
| │ bootstrap-theme.css.map |
| │ bootstrap-theme.min.css |
| │ bootstrap-theme.min.css.map |
| │ bootstrap.css |
| │ bootstrap.css.map |
| │ bootstrap.min.css |
| │ bootstrap.min.css.map |
| │ |
| ├─templates |
| base.html |
| detail.html |
css文件夹: 是从我们上面下载好的用于生产环境的 Bootstrap
中解压出来的
base.html 注意:里面的form
标签中的内容和nav
标签中的内容均是bootstrap框架的代码截取,div
标签是用于清除浮动
| <!DOCTYPE html> |
| <html lang="en"> |
| <head> |
| <meta charset="UTF-8"> |
| <title>父模板</title> |
| <link rel="stylesheet" href="{{ url_for('static',filename='css/bootstrap.css') }}"> |
| </head> |
| <body> |
| <form class="navbar-form navbar-left" role="search"> |
| <div class="form-group"> |
| <input type="text" class="form-control" placeholder="Search"> |
| </div> |
| <button type="submit" class="btn btn-default">Submit</button> |
| </form> |
| <div style=" visibility:hidden;display:block;font-size:0;clear:both; |
| height:50px"></div> |
| |
| {% block main %} |
| <p>父模板中main中原有的内容</p> |
| |
| {% endblock %} |
| <br> |
| <br> |
| <br> |
| {% block demo %} |
| <p>demo中原有的内容</p> |
| {% endblock %} |
| |
| <div style=" visibility:hidden;display:block;font-size:0;clear:both; |
| height:0"></div> |
| <nav aria-label="Page navigation"> |
| <ul class="pagination"> |
| <li> |
| <a href="#" aria-label="Previous"> |
| <span aria-hidden="true">«</span> |
| </a> |
| </li> |
| <li><a href="#">1</a></li> |
| <li><a href="#">2</a></li> |
| <li><a href="#">3</a></li> |
| <li><a href="#">4</a></li> |
| <li><a href="#">5</a></li> |
| <li> |
| <a href="#" aria-label="Next"> |
| <span aria-hidden="true">»</span> |
| </a> |
| </li> |
| </ul> |
| </nav> |
| |
| </body> |
| </html> |
detail.html
| {% extends 'base.html' %} |
| {% block demo %} |
| <p>子模板中重写demo的内容</p> |
| {% endblock %} |
| {% block main %} |
| {{ super() }} {# 保留基模板中本block的代码 #} |
| {{ self.demo() }} {# 调用demo block的代码 #} |
| <p>子模板中重写main的内容 </p> |
| {% endblock %} |
app.py 注意:app.config.update(TEMPLATES_AUTO_RELOAD=True)
语句用于每次都重新加载模板文件
| from flask import Flask, render_template |
| |
| app = Flask(__name__) |
| app.config.update(TEMPLATES_AUTO_RELOAD=True) |
| |
| @app.route('/') |
| def hello_world(): |
| return render_template('base.html') |
| |
| @app.route('/demo/') |
| def demo(): |
| return render_template('detail.html') |
| |
| if __name__ == '__main__': |
| app.run() |
子模板运行效果
Flask 提供了一个非常简单的方法来使用闪现系统向用户反馈信息。闪现系统使得在一个请求结束的时候记录一个信息,然后在且仅仅在下一个请求中访问这个数据
,强调flask闪现是基于flask
内置的session
的,利用浏览器的session
缓存闪现信息。所以必须设置secret_key
。
实例:
server.py
| from flask import Flask, flash, redirect, render_template, \ |
| request, url_for |
| |
| app = Flask(__name__) |
| app.secret_key = 'some_secret' |
| |
| @app.route('/') |
| def index(): |
| return render_template('index.html') |
| |
| @app.route('/login', methods=['GET', 'POST']) |
| def login(): |
| error = None |
| if request.method == 'POST': |
| if request.form['username'] != 'admin' or \ |
| request.form['password'] != '123': |
| error = '登录失败' |
| else: |
| flash('恭喜您登录成功') |
| return redirect(url_for('index')) |
| return render_template('login.html', error=error) |
| |
| if __name__ == "__main__": |
| app.run() |
注意:这个 flash()
就可以实现在下一次请求时候,将括号内的信息做一个缓存。不要忘记设置secret_key
这里是 index.html 模板:
| {% with messages = get_flashed_messages() %} # 获取所有的闪现信息返回一个列表 |
| {% if messages %} |
| <ul class=flashes> |
| {% for message in messages %} |
| <li>{{ message }}</li> |
| {% endfor %} |
| </ul> |
| {% endif %} |
| {% endwith %} |
| |
| <h1>主页</h1> |
| <p>跳转到登录页面<a href="{{ url_for('login') }}">登录?</a> |
注意:{% with messages = get_flashed_messages() %} # 获取所有的闪现信息返回一个列表
这里是login.html 模板
| <h1>登录页面</h1> |
| {% if error %} |
| <p class=error><strong>Error:</strong> {{ error }} |
| {% endif %} |
| <form action="" method=post> |
| 用户名: |
| <input type=text name=username> |
| 密码: |
| <input type=password name=password> |
| <p><input type=submit value=Login></p> |
| </form> |
简单的在模板中实现获取闪现信息小结:
| 设置闪现内容:flash('恭喜您登录成功') |
| 模板取出闪现内容:{% with messages = get_flashed_messages() %} |
当闪现一个消息时,是可以提供一个分类的。未指定分类时默认的分类为 'message'
。 可以使用分类来提供给用户更好的反馈,可以给用户更精准的提示信息体验。
要使用一个自定义的分类,只要使用 flash()
函数的第二个参数:
| flash('恭喜您登录成功',"status") |
| flash('您的账户名为admin',"username") |
在使用get_flashed_messages()
时候需要传入with_categories=true
便可以渲染出来类别
| {% with messages = get_flashed_messages(with_categories=true) %} |
| {% if messages %} |
| <ul class=flashes> |
| {% for category, message in messages %} |
| <li class="{{ category }}">{{ category }}:{{ message }}</li> |
| {% endfor %} |
| </ul> |
| {% endif %} |
| {% endwith %} |
模板中的分类闪现小结:
| 分类设置闪现内容:flash('恭喜您登录成功',"status") |
| flash('您的账户名为admin',"username") |
| 模板取值: {% with messages = get_flashed_messages(with_categories=true) %} |
| {% if messages %} |
| <ul class=flashes> |
| {% for category, message in messages %} |
| ... |
| |
同样要使用一个自定义的分类,只要使用 flash()
函数的第二个参数:
| flash('恭喜您登录成功',"status") |
| flash('您的账户名为admin',"username") |
在使用get_flashed_messages()
时候需要传入category_filter=["username"]
便可根据类别取出闪现信息。中括号内可以传入的值就是类别,可以传入多个。
| {% with messages = get_flashed_messages(category_filter=["username"]) %} |
| {% if messages %} |
| <ul> |
| {%- for message in messages %} |
| <li>{{ message }}</li> |
| {% endfor -%} |
| </ul> |
| </div> |
| {% endif %} |
| {% endwith %} |
小结:
| 分类设置闪现内容:flash('恭喜您登录成功',"status") |
| flash('您的账户名为admin',"username") |
| 模板取值: % with messages = get_flashed_messages(category_filter=["username"]) %} |
| {% if messages %} |
| <ul> |
| {%- for message in messages %} |
| -设置: flash('xxx') |
| -取值:get_flashed_message() |
| -注意:在视图中获取闪现信息不必非得是两次连续的请求,只要保证是第一次取相应的闪现信息,就可以取得到。 |
实例:
| from flask import Flask, request, flash, get_flashed_messages |
| import os |
| |
| app = Flask(__name__) |
| app.secret_key = os.urandom(4) |
| app.debug = True |
| |
| @app.route('/login/') |
| def login(): |
| if request.args.get('name') == 'rocky': |
| return 'ok' |
| flash('第一条闪现信息:用户名不是rocky填写的是{}'.format(request.args.get('name'))) |
| |
| return 'error,设置了闪现' |
| @app.route('/get_flash/') |
| def get_flash(): |
| |
| return '闪现的信息是{}'.format(get_flashed_messages()) |
| |
| @app.route('/demo/') |
| def demo(): |
| return 'demo' |
| |
| if __name__ == '__main__': |
| app.run() |
(1)**会触发设置闪现内容
(2)取出闪现内容
(3)再次取出闪现内容,发现闪现内容取出一次后就为空了
小结:
- get_flashed_messages()是一个列表,该列表可以取出闪现信息,该条闪现信息只要被取出就会删除掉。
| -设置:flash('用户名错误', "username_error") |
| flash('用户密码错误', "password_error") |
| |
| -取所有闪现信息的类别和闪现内容:get_flashed_messages(with_categories=True) |
| |
| -针对分类过滤取值:get_flashed_messages(category_filter=['username_error']) |
| |
| |
| -注意:如果flash()没有传入第二个参数进行分类,默认分类是 'message' |
实例1
| @app.route('/login/') |
| def login(): |
| if request.args.get('name') == 'rocky': |
| return 'ok' |
| flash('用户名错误', category="username_error") |
| flash('用户密码错误', "password_error") |
| return 'error,设置了闪现' |
| @app.route('/get_flash/') |
| def get_flash(): |
| return '闪现的信息是{}'.format(get_flashed_messages(with_categories=True)) |
把所有的闪现类别和闪现信息返回。
实例2
| @app.route('/login/') |
| def login(): |
| if request.args.get('name') == 'rocky': |
| return 'ok' |
| flash('用户名错误', category="username_error") |
| flash('用户密码错误', "password_error") |
| return 'error,设置了闪现' |
| @app.route('/get_flash/') |
| def get_flash(): |
| return '闪现的信息是{}'.format(get_flashed_messages(category_filter=['username_error'])) |
返回页面只显示了 "username_error"
的分类内容。