flask内容学习第二天
Posted cerofang
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了flask内容学习第二天相关的知识,希望对你有一定的参考价值。
异常的捕获
1 from flask import Flask 2 from flask import abort 3 4 app = Flask(__name__) 5 6 7 @app.route(‘/‘) 8 def hello_world(): 9 return ‘Hello World!‘ 10 11 12 @app.route("/demo1") 13 def demo1(): 14 # 主动http状态码 15 abort(404) 16 return "demo1" 17 18 19 # 使用装饰器来捕获异常指定的状态码和异常 20 @app.errorhandler(404) 21 def page_not_fund(error): 22 print(error) 23 return "页面不存在" 24 25 26 @app.route("/demo2") 27 def div_demo2(): 28 a = 5 29 b = 0 30 return a / b 31 32 33 # 使用错误捕获来捕获除数不能为0的的错误 34 @app.errorhandler(ZeroDivisionError) 35 def Zero_Division_Error(error): 36 print(error) 37 return "除数不能为0" 38 39 40 # 第二种捕获异常的方式 41 # def page_not_found(error): 42 # return ‘你访问的页面不存在‘, 404 43 # app.error_handler_spec[None][404] = page_not_found 44 45 46 47 if __name__ == ‘__main__‘: 48 app.run(debug=True)
注册一个处理程序错误的装饰器,当程序抛出指定错误状态码的时候会调用装饰器所装饰的方法(除了捕获异常的状态码之外还可以捕获指定的异常)
flask中的请求钩子
1 #! /usr/bin/env python 2 # *-* coding: utf-8 *-* 3 4 from flask import Flask 5 6 app = Flask(__name__) 7 8 9 @app.before_first_request 10 def before_first_request(): 11 print("before_first_request") 12 13 14 @app.before_request 15 def before_request(): 16 print("before_request") 17 18 19 @app.after_request 20 def after_request(response): 21 print("response", response) 22 print("after_request") 23 return response 24 25 26 # 在请求之后可以被执行,如果有异常会将此异常传入到这个函数来做处理 27 @app.teardown_request 28 def teardown_request(error): 29 print(error) 30 print("teardown_request") 31 32 33 @app.route(‘/‘) 34 def index(): 35 print("index", index) 36 return ‘index‘ 37 38 39 if __name__ == ‘__main__‘: 40 app.run(debug=True)
before_first_request(在处理第一个请求前执行,后续的执行过程就不会再执行了)
before_request(每次发起请求前都会执行,如果在某个修饰函数中返回一个响应,视图函数将不再被调用)
after_request
(
没有抛出异常,则在每次请求后会执行
接收一个参数:视图函数做出的响应;
在此函数中可以对视图函数做出的响应做最后一步的处理;
需要将参数中的响应在此函数中返回
)
teardown_request
(
每次请求之后都会执行;
接收一个参数:如果抛出异常,则参数会捕捉到这个异常;
)
1 #! /usr/bin/env python 2 # *-* coding: utf-8 *-* 3 4 from flask import Flask,request 5 from werkzeug.serving import run_simple 6 7 app = Flask(__name__) 8 9 10 @app.route(‘/‘) 11 def hello_world(): 12 return ‘Hello World!‘ 13 14 @app.route(‘/index‘, methods=["POST",]) 15 def index(): 16 print(request.method) 17 return ‘index index!‘ 18 19 # rule 视图函数和酷游关系的映射关系 20 # map rule的集合 21 # BaseConverter匹配路由匹配的规则 22 # MapAdapter协调以上的路由匹配的工作 23 24 25 if __name__ == ‘__main__‘: 26 print(app.url_map) 27 app.run(debug=True)
Werkzeug库的 routing 模块负责实现 URL 解析。不同的 URL 对应不同的视图函数,routing模块会对请求信息的URL进行解析,匹配到URL对应的视图函数,执行该函数以此生成一个响应信息。
routing模块内部有:
- Rule类
- 用来构造不同的URL模式的对象,路由URL规则
- Map类
- 存储所有的URL规则和一些配置参数
- BaseConverter的子类
- 负责定义匹配规则
- MapAdapter类
- 负责协调Rule做具体的匹配的工作
1 #! /usr/bin/env python 2 # *-* coding: utf-8 *-* 3 4 5 from flask import Flask 6 from flask import request 7 8 app = Flask(__name__) 9 10 11 @app.route(‘/index‘, methods=["GET", "POST"]) 12 def index(): 13 return ‘Hello World!‘ 14 15 16 @app.route("/args", methods=["GET", "POST"]) 17 def args(): 18 # get方式地址栏传递参数 19 print(request.form.get("name")) 20 print(request.form.get("age")) 21 # post方式请求体中传递参数 22 print(request.args.get("name")) 23 print(request.args.get("age")) 24 return "success" 25 26 27 @app.route("/file", methods=["POST"]) 28 def up_load_file(): 29 print(request.method) 30 pic = request.files.get("pic") 31 pic.save("./static/aaaa.png") 32 return "success" 33 34 35 if __name__ == ‘__main__‘: 36 app.run(debug=True)
request是flask中代表当前请求的request对象,是一个全局的请求上下文的一个变量(可以理解成为一个全局变量,在视图函数中可以直接使用,可以取到当前请求)。
备注:在地址栏中请求数据的方式可以用args的方式去在request中取值,如果在form表单中的数据需要在form中取值。
cookie的设置
1 #! /usr/bin/env python 2 # *-* coding: utf-8 *-* 3 4 from flask import Flask 5 from flask import request 6 from flask import make_response 7 8 app = Flask(__name__) 9 10 11 # 获取cookies 12 @app.route(‘/index‘) 13 def index(): 14 username = request.cookies.get("username") 15 user_id = request.cookies.get("user_id") 16 return ‘%s---%s‘ % (username, user_id) 17 18 19 # 设置cookies 20 @app.route("/login") 21 def login(): 22 response = make_response("success") 23 response.set_cookie("username", "xiaoimng", max_age=3600) 24 response.set_cookie("user_id", "1", max_age=3600) 25 return response 26 27 28 # 删除cookies 29 @app.route("/logout") 30 def logout(): 31 32 response = make_response("删除cookies成功") 33 response.delete_cookie("user_id") 34 response.delete_cookie("username") 35 return response 36 37 38 if __name__ == ‘__main__‘: 39 app.run(debug=True)
备注:
1,cookie的设置是在response中进行设置,在request中取值;
2,http是一种无状态的协议,浏览器在请求服务器的时候是无状态的,
无状态的原因是:
浏览器与服务器通过socket进行通信,服务器会将请求结果返回给浏览器,请求完毕后服务器都会将通信套接字关闭,并且服务器在关闭套接字之后就会销毁请求的页面的对象;
有时需要保持浏览器的状态,比如用户的登录状态,和浏览过的信息等;
无状态协议
1,协议对事物的处理没有记忆的功能;
2,对于同一个url请求没有上下文的关系;
3,每次执行的结果都是独立的,它执行的结果和情况与上前面的请求和之后的请求没有直接的关系,它不会受前面的请求应答的影响,也不会对后面的请求应答产生影响;
4,服务器没有保持客户端的状态,客户端每次需要自己将状态带到服务区端;
实现状态保持有两种方式;
1,在客户端设置cookie,在每次发送请求的时候将cookie带给服务器端;
2,在服务器端设置session,每次客户福安发送来请求之后,将客户端的cookie与session做做对比;(所有说session是依赖于cookie的,cookie可以单独存在session不可以独立存在);
1 #! /usr/bin/env python 2 # *-* coding: utf-8 *-* 3 from datetime import timedelta 4 from flask import Flask 5 from flask import session 6 7 app = Flask(__name__) 8 app.config["SECRET_KEY"] = "abcdefg" 9 10 11 # app.secret_key["SECRET_KEY"] = "abcsefght" 12 13 @app.route(‘/index‘) 14 def index(): 15 user_name = session.get("user_name") 16 user_id = session.get("user_id") 17 return "%s---%s" % (user_name, user_id) 18 19 20 @app.route("/login") 21 def login(): 22 session.permanent = True 23 app.permanent_session_lifetime = timedelta(second=10) 24 session["user_name"] = "xiaomingh" 25 session["user_id"] = "1" 26 return "session设置成功" 27 28 29 @app.route("/logout") 30 def logout(): 31 session.pop("user_name", None) 32 session.pop("user_id", None) 33 return "session删除删除成功" 34 35 36 if __name__ == ‘__main__‘: 37 app.run(debug=True)
请求上下文(request context)
思考:在视图函数中,如何取到当前请求的相关数据?比如:请求地址,请求方式,cookie等等
在 flask 中,可以直接在视图函数中使用 request 这个对象进行获取相关数据,而 request 就是请求上下文的对象,保存了当前本次请求的相关数据,请求上下文对象有:request、session
- request
- 封装了HTTP请求的内容,针对的是http请求。举例:user = request.args.get(‘user‘),获取的是get请求的参数。
- session
- 用来记录请求会话中的信息,针对的是用户信息。举例:session[‘name‘] = user.id,可以记录用户信息。还可以通过session.get(‘name‘)获取用户信息。
应用上下文(application context)
它的字面意思是 应用上下文,但它不是一直存在的,它只是request context 中的一个对 app 的代理(人),所谓local proxy。它的作用主要是帮助 request 获取当前的应用,它是伴 request 而生,随 request 而灭的。
应用上下文对象有:current_app,g
current_app
应用程序上下文,用于存储应用程序中的变量,可以通过current_app.name打印当前app的名称,也可以在current_app中存储一些变量,例如:
- 应用的启动脚本是哪个文件,启动时指定了哪些参数
- 加载了哪些配置文件,导入了哪些配置
- 连了哪个数据库
- 有哪些public的工具类、常量
- 应用跑再哪个机器上,IP多少,内存多大
current_app.name
current_app.test_value=‘value‘
g变量
g 作为 flask 程序全局的一个临时变量,充当者中间媒介的作用,我们可以通过它传递一些数据,g 保存的是当前请求的全局变量,不同的请求会有不同的全局变量,通过不同的thread id区别
g.name=‘abc‘
注意:不同的请求,会有不同的全局变量
flask_script
1 #! /usr/bin/env python 2 # *-* coding: utf-8 *-* 3 4 5 from flask import Flask 6 # 请求上下文的变量 7 from flask import request, make_response 8 # 运用上下文的变量 9 from flask_script import Manager 10 from flask import current_app 11 from flask import g 12 13 app = Flask(__name__) 14 app.debug = True 15 manager = Manager(app) 16 17 18 @app.route(‘/‘) 19 def hello_world(): 20 # 类似于一个全局变量的东西 21 print(current_app.config.get("DEBUG")) 22 return ‘Hello World!‘ 23 24 25 if __name__ == ‘__main__‘: 26 manager.run() 27 # app.run(debug=True)
通过使用Flask-Script扩展,我们可以在Flask服务器启动的时候,通过命令行的方式传入参数。而不仅仅通过app.run()方法中传参,比如我们可以通过:
python hello.py runserver -host ip地址
以上是关于flask内容学习第二天的主要内容,如果未能解决你的问题,请参考以下文章