Flaks完整框架流程图解
Flask请求响应 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 from flask import Flask,jsonifyfrom flask import views from flask import Flaskfrom flask import requestfrom flask import render_templatefrom flask import redirectfrom flask import make_responseapp = Flask(__name__) app.debug=True @app.route('/login.html' , methods=['GET' , "POST" ] ) def login ():
请求相关信息 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 request.method print (request.args.get('name' )) print (request.form) print (request.values) print (request.query_string) request.args request.form request.values request.cookies request.headers request.path request.full_path request.url request.base_url request.url_root request.host_url request.host request.files obj = request.files['the_file_name' ] obj.save('/var/www/uploads/' + secure_filename(f.filename))
flask新手四件套 1 2 3 4 return "字符串" return render_template('html模板路径' ,**{})return redirect('/index.html' )return jsonify({'k1' :'v1' })
响应相关信息(响应response增加数据返回) 1 2 3 4 5 6 7 8 9 10 11 12 response = make_response(render_template('index.html' )) response = make_response('hello' ) response.delete_cookie('session' ) response.set_cookie('name' , 'lqz' ) response.headers['X-Something' ] = 'A value' return response if __name__ == '__main__' : app.run(port=8888 )
session session与cookie简介
cookie:存放在客户端的键值对
session:存放在客户端的键值对
token:存放在客户端,通过算法来校验
在使用session之前必须现在设置一下密钥
dajngo中session与Flask的session差别
在django中发什么三件事: 1 生成一个随机的字符串 2 往数据库存 3 写入cookie返回浏览器
在flask中没有数据库,但session是怎样实现的? 生成一个密钥写入这个cookie,然后下次请求的时候,通过这个cookie解密,然后赋值给session
session使用 1 2 3 -增:session['name' ]=lqz -查:session.get('name' ) -删:session.pop('name' )
set_cookie其他参数 1 2 3 4 5 6 7 8 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获取(不是绝对,底层抓包可以获取到也可以被覆盖)
整体代码 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 from flask import Flask,jsonifyfrom flask import views from flask import Flask,sessionfrom flask import requestfrom flask import render_templatefrom flask import redirectfrom flask import make_responseapp = Flask(__name__) app.debug=True app.secret_key='sdfsdfsadfasdf' app.session_interface @app.route('/login.html' , methods=['GET' , "POST" ] ) def login (): session['name' ]='lqz' response=make_response('hello' ) return response @app.route('/index' , methods=['GET' , "POST" ] ) def index (): print (session.get('name' )) return '我是首页' if __name__ == '__main__' : app.run(port=8080 )
源码分析SecureCookieSessionInterface flask框架session源码分析
分析SecureCookieSessionInterface
分析save_seesion响应与open_session请求来的时候 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 1. save_seesion -响应的时候,把session中的值加密序列化放大到了cookie中,返回到浏览器中 """ # 将session设置成字典类型序列化转换成json字符串 val = self.get_signing_serializer(app).dumps(dict(session)) # 1.响应对象内设置session response.set_cookie( # 2.session的id app.session_cookie_name, # 3.session的value val, expires=expires, ) """ 2. open_session -请求来了,从cookie中取出值,反解,生成session对象,以后再视图函数中直接用sessoin就可以了。 """ # 1.取出request.cookies中的value值 val = request.cookies.get(app.session_cookie_name) # 2.将session的value值取出来反序列化 data = s.loads(val, max_age=max_age) # 3.返回session(data) return self.session_class(data) """
整体代码 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 from flask import Flask,jsonifyfrom flask import views from flask import Flask,sessionfrom flask import requestfrom flask import render_templatefrom flask import redirectfrom flask import make_responseapp = Flask(__name__) app.debug=True app.secret_key='sdfsdfsadfasdf' app.session_interface @app.route('/login.html' , methods=['GET' , "POST" ] ) def login (): session['name' ]='lqz' response=make_response('hello' ) return response @app.route('/index' , methods=['GET' , "POST" ] ) def index (): print (session.get('name' )) return '我是首页' if __name__ == '__main__' : app.run(port=8080 )
闪现
设置:flash(‘aaa’)
取值:get_flashed_message()
假设在a页面操作出错,跳转到b页面,在b页面显示a页面的错误信息
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 from flask import Flask,flash,get_flashed_messages,request,redirect app = Flask(__name__) app.secret_key = 'asdfasdf' @app.route('/user' , methods=['GET' , "POST" ] ) def login (): try : a=[1 ,2 ,3 ] print (a[9 ]) except Exception as e: print (e) flash(str (e)) flash('超时错误' , category="x1" ) flash('xx错误' , category="x3" ) return response @app.route('/error' , methods=['GET' , "POST" ] ) def error (): errors=get_flashed_messages() errors=get_flashed_messages(category_filter=['x1' ]) return render_template('error.html' ,errors=errors) if __name__ == '__main__' : app.run()
请求扩展 before_request 1 2 1. 类比django中间件中的process_request,写多个执行顺序是从上往下
1 2 3 4 5 6 7 8 9 @app.before_request def process_request (*args,**kwargs ): if request.path == '/login' : return None user = session.get('user_info' ) if user: return None return redirect('/login' )
after_request 1 2 1. 类比django中间件中的process_response,每一个请求之后绑定一个函数,如果请求没有异常
1 2 3 4 @app.after_request def process_response1 (response ): print ('process_response1 走了' ) return response
before_first_request
1 2 3 @app.before_first_request def first (): pass
teardown_request 1 2 3 4 1. 每一个请求之后绑定一个函数,即使遇到了异常
1 2 3 @app.teardown_request def ter (e ): pass
errorhandler
1 2 3 @app.errorhandler(404 ) def error_404 (arg ): return "404错误了"
template_global 自定义标签
1 2 3 4 @app.template_global() def sb (a1, a2 ): return a1 + a2
template_filter 自定义过滤器
1 2 3 4 @app.template_filter() def db (a1, a2, a3 ): return a1 + a2 + a3
总结
重点掌握before_request和after_request,
注意有多个的情况,执行顺序
before_request请求拦截后(也就是有return值),response所有都执行
中间件(了解) 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 from flask import Flask app = Flask(__name__) @app.route('/' ) def index (): return 'Hello World!' class Md (object ): def __init__ (self,old_wsgi_app ): self.old_wsgi_app = old_wsgi_app def __call__ (self, environ, start_response ): print ('开始之前' ) ret = self.old_wsgi_app(environ, start_response) print ('结束之后' ) return ret if __name__ == '__main__' : app.wsgi_app = Md(app.wsgi_app) app.run()
请求所有的流程
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 ctx = self.request_context(environ) error = None try : try : ctx.push() response = self.full_dispatch_request() except Exception as e: error = e response = self.handle_exception(e) except : error = sys.exc_info()[1 ] raise return response(environ, start_response) finally : if self.should_ignore_error(error): error = None ctx.auto_pop(error)
蓝图 对程序进行目录结构 划分
使用步骤
1.实例化得到一个蓝图对象(可以指定直接的静态文件和模板路径) 2.在app中注册蓝图(可以指定前缀) 3.以后再写路由装饰器,使用蓝图对象的.route
不使用蓝图,自己分文件
目录结构:
-templates
-views
-__init__.py
-user.py
-order.py
-app.py
app.py
1 2 3 from views import appif __name__ == '__main__' : app.run()
init.py
1 2 3 4 5 6 from flask import Flask,requestapp = Flask(__name__) from . import accountfrom . import orderfrom . import user
user.py
1 2 3 4 from . import app@app.route('/user' ) def user (): return 'user'
order.py
1 2 3 4 from . import app@app.route('/order' ) def order (): return 'order'