flask框架(五)——支持正则写法、模板用法、请求响应、session
如果用正则的话,我们要用自定义的路由。
1导入from werkzeug.routing import BaseConverter 2我先要写一个类,然后继承BaseConverter,然后实现__init__, to_python(self, value),to_url(self, value) 这三个方法 3 app.url_map.converters['随便写'] = RegexConverter 4 我们在路由里面@app.route('/index/<regex1("\d+"):nid>'),regex1是随便写,regex1("正则表达式") 5 regex1("正则表达式")匹配出来的结果,返回to_python,一定要return (视图函数的参数能接收到to_python的返回值) 6 当我们做反向解析的解析的时候,传递的参数,会传递给to_url,return的结果是拼接到我们路由上
代码示例:
from flask import Flask,url_for from werkzeug.routing import BaseConverter app = Flask(import_name=__name__) class RegexConverter(BaseConverter): """ 自定义URL匹配正则表达式 """ def __init__(self, map, regex): super(RegexConverter, self).__init__(map) self.regex = regex def to_python(self, value): """ 路由匹配时,匹配成功后传递给视图函数中参数nid """ #value就正则匹配出来的结果 print('value',value,type(value)) return "asdasdasd" #返回值返回给视图函数中的参数 def to_url(self, value): """ 使用url_for反向生成URL时,传递的参数经过该方法处理,返回的值用于生成URL中的参数 """ val = super(RegexConverter, self).to_url(value) print(val) #val是传入的nid值 return val #返回值用于拼接成路径 app.url_map.converters['regex1'] = RegexConverter @app.route('/index/<regex1("\d+"):nid>',endpoint="sb") def index(nid): print("nid",nid,type(nid)) print(url_for('sb', nid='888')) #/index/888 return 'Index' if __name__ == '__main__': app.run()
模板
模板传递参数、变量的循环、传递html语言代码并且识别
test1.py
USERS = {
1:{'name':'张三','age':18,'gender':'男','text':"道路千万条"},
2:{'name':'李四','age':28,'gender':'男','text':"安全第一条"},
3:{'name':'王五','age':18,'gender':'女','text':"行车不规范"},
}
def func1(st,st1): return Markup(f"<h1>jsaon-gdx{st}{st1}</h1>") @app.route('/list',methods=['GET']) def list(): info=USERS return render_template('list.html',info1=info,html="<h1>jsaon-gdx</h1>",html1=func1)
list.html (注意:后台传递参数值是info1,前台接收参数也要写info1)
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> {% for k,v in info1.items() %} #后台传递的info1参数 <tr> <td>{{k}}</td> <td>{{v.name}}</td> <td>{{v['name']}}</td> <td>{{v.get('name')}}</td> <td><a href="{{url_for('sb',nid=k)}}">查看详细</a></td> </tr> {% endfor %} {{html|safe}} #传递的html语句,使用|safe能取消转义,从字符串变成能正常显示的html语法 {{html1("-DSB","-SB")}} #使用Markup,能传递html语句,并且可以传参 </body> </html>
注意:Mark等价于django的mark_safe
在html中也能通过url_for反向解析路径,并且能够传参(******)
test.py
@app.route('/detail/<int:nid>',methods=['GET'],endpoint="sb") def detail(nid): return "ok"
list.html (在detail视图函数中设置好别名,)
<td><a href="{{url_for('sb',nid=k)}}">查看详细</a></td> #路由跳转,并且把k值传递给nid
请求响应
from flask import Flask from flask import request from flask import render_template from flask import redirect from flask import make_response app = Flask(__name__) @app.route('/login.html', methods=['GET', "POST"]) def login(): # 请求相关信息 # request.method 提交的方法 # request.args get请求提及的数据 # request.form post请求提交的数据 # request.values post和get提交的数据总和 # request.cookies 客户端所带的cookie # request.headers 请求头 # request.path 不带域名,请求路径 # request.full_path 不带域名,带参数的请求路径 # request.script_root # request.url 带域名带参数的请求路径 # request.base_url 带域名请求路径 # request.url_root 域名 # request.host_url 域名 # request.host 127.0.0.1:500 # request.files # obj = request.files['the_file_name'] # obj.save('/var/www/uploads/' + secure_filename(f.filename)) 响应相关信息(4剑客) # return "字符串" # return render_template('html模板路径',**{}) # return redirect('/index.html') #return jsonify({'k1':'v1'}) # response = make_response(render_template('index.html')) # response是flask.wrappers.Response类型 # response.delete_cookie('key') # response.set_cookie('key', 'value') # response.headers['X-Something'] = 'A value' # return response return "内容" if __name__ == '__main__': app.run()
session
cookie:存放在客户端的键值对
session:存放在客户端的键值对
token:存放在客户端,通过算法来校验
在使用session之前必须设置一下密钥
app = Flask(__name__) app.secret_key="askjdaksd" #随便写
除请求对象之外,还有一个 session 对象。它允许你在不同请求间存储特定用户的信息。它是在 Cookies 的基础上实现的,并且对 Cookies 进行密钥签名,要使用会话你需要设置一个密钥。 (app.session_interface对象)
到源码app.session_interface这里面看(******) 存session: 1 调用save_session,将我们的session加密的val,读取配置文件['SESSION_COOKIE_NAME']得到key 2 将1中的key,val存储到cookies 取session: 1 获取request里面的cookies,获取里面key,这个key就是['SESSION_COOKIE_NAME'],值就是加密的值 2 对该值进行解密
app.session_interface中save_session的参数(设置cookie的参数)
key, 键 value='', 值 max_age=None, 超时时间 cookie需要延续的时间(以秒为单位)如果参数是\ None`` ,这个cookie会延续到浏览器关闭为止 expires=None, 超时时间(IE requires expires, so set it if hasn't been already.) path='/', Cookie生效的路径,/ 表示根路径,特殊的:根路径的cookie可以被任何url的页面访问,浏览器只会把cookie回传给带有该路径的页面,这样可以避免将cookie传给站点中的其他的应用。 domain=None, Cookie生效的域名 你可用这个参数来构造一个跨站cookie。如, domain=".example.com"所构造的cookie对下面这些站点都是可读的:www.example.com 、 www2.example.com 和an.other.sub.domain.example.com 。如果该参数设置为 None ,cookie只能由设置它的站点读取 secure=False, 浏览器将通过HTTPS来回传cookie httponly=False 只能http协议传输,无法被JavaScript获取(不是绝对,底层抓包可以获取到也可以被覆盖)
session源码执行流程
-save_seesion -响应的时候,把session中的值加密序列化放大到了cookie中,返回到浏览器中 -open_session -请求来了,从cookie中取出值,反解,生成session对象,以后再视图函数中直接用sessoin就可以了。
代码示例:
from flask import Flask,session app = Flask(__name__) app.secret_key="askjdaksd" app.config['SESSION_COOKIE_NAME']="dsb" @app.route("/") def index(): session['jason']="gdx" return "ok" @app.route("/index1") def index1(): print(session['jason']) return "ok1" if __name__ == '__main__': app.run()