很久没有更新flask框架的内容了,最近都在忙家里的事情,也在算法入门中。
————2022年12月31日
目录
before_first_request和before_request详解
Flask_线程隔离的g对象
全局对象g对象的好处:
1.g对象在整个Flask应用运行期间都是可以使用的。
2.跟request一样,是线程隔离的。
3.g对象是专门用来储存开发者自己定义的数据的,方便在整个Flask程序中都可以去使用。一般的使用是,将一些经常会用到的数据绑在上面,使用时可以直接从g上面取,不需要通过传参的方式。
例:
from flask import Flask from utils import * import utils_new as n app = Flask(__name__) @app.route('/') def index(): uname = 'xiaolin' a = func_a(uname) b = func_b(uname) c = func_c(uname) return f'hello! <br> {a} <br> {b} <br> {c}' @app.route('/new/') def index_new(): uname = 'xiaolin' g.uname = uname a = n.func_a() b = n.func_b() c = n.func_c() return f'hello! <br> {a} <br> {b} <br> {c}' if __name__ == '__main__': app.run(debug=True)
钩子函数 (灵活追加代码的功能)
在Flask中钩子函数就是使用特定装饰器装饰的函数。
我也不理解为什么叫钩子函数,反正就是可以在正常执行的代码中,插入一段自己想要执行的代码的函数,就是钩子函数了。
常见的钩子函数:
1.before_first_request:处理项目的第一次请求之前执行。
@app.before_first_request def first_request(): print('first time request')
2.before_request:在每次请求之前执行。通常可以用这个装饰器来给视图函数增加一些变量。请求已经到达了Flask,但是还没有进入到具体的视图函数之前调用。一般这个就是在视图函数之前,我们可以把一些后面需要用到的数据先处理好,方便视图函数使用。
@app.before_request def before_request(): if not hasattr(g,'glo1'): setattr(g,'glo1','想要设置的')
3.teardown_appcontext:不管是否有异常,注册的函数都会在每次请求之后执行。
@app.teardown_appcontext def teardown(exc=None): if exc is None: db.session.commit() else: db.session.rollback() db.session.remove()
4.template_filter:在使用Jinja2模板的时候自定义过滤器。
@app.template_filter("upper") def upper_filter(s): return s.upper()
5.context_processor:上下文处理器。使用这个钩子函数,必须返回一个字典。这个字典中的值在所有模版中都可以使用。这个钩子函数的函数是,如果一些在很多模版中都要用到的变量,那么就可以使用这个钩子函数来返回,而不用在每个视图函数中的render_template中去写,这样可以让代码更加简洁和好维护。
@app.context_processor def context_processor(): if hasattr(g,'user'): return {"current_user":g.user} else: return {}
6.errorhandler:errorhandler接收状态码,可以自定义返回这种状态码的响应的处理方法。在发生一些异常的时候,比如404错误,比如500错误,那么如果想要优雅的处理这些错误,就可以使用errorhandler
来出来。
@app.errorhandler(404) def page_not_found(error): return 'This page does not exist',404
before_first_request和before_request详解
这两个函数都是在请求前进行追加功能。
before_first_request:
from flask import Flask,request app = Flask(__name__) @app.route('/') def hello_world(): print("hi") return "hello world " @app.before_first_request def first_request(): print('hello world') if __name__ == '__main__': app.run(debug=True)
bofore_request:
from flask import Flask,g,session app = Flask(__name__) app.config['SECRET_KEY'] = 'skidhfikshighsd' @app.route('/login/') def login(): print('运行代码 222222222') print('Hello!!!!') session['uname'] = '小林' return f'Hello' @app.route('/home/') def home(): print('运行代码 3333333333') if hasattr(g, 'uname'): return f'用户已登录!用户名是:{g.uname}' return '用户没有登录!' @app.before_request def before_request(): print('运行代码 111111111111') uname = session.get('uname') if uname: g.uname = uname print('这个是每次请求时,需要执行的逻辑!!!') # 需求: 判断用户是否登录,如果登录了,就返回用户的信息,如果没有登录就返回None if __name__ == '__main__': app.run(debug = True)
context_processor详解
使用场景
这个钩子函数的功能是,如果一些在很多模版中都要用到的变量,那么就可以使用这个钩子函数来返回,而不用在每个视图函数中的render_template
中去写,这样可以让代码更加简洁和好维护。
from flask import Flask,request,session,current_app,url_for,g,render_template import os app = Flask(__name__) app.config['SECRET_KEY']=os.urandom(24) #加盐 混淆原数据的作用 @app.route('/') def hello_world(): print("hi") session['uname']="sxt" # return "hello world " return render_template("index.html") @app.route('/li') def mylist(): print("mylist") # print("直接取出",g.user) if hasattr(g,"user"): print("条件取出", g.user) # return "hello world " return render_template('list.html') @app.before_request def before_request(): # print('在视图函数执行之前执行的钩子函数') # 场景:若用户已经登录了,验证时把用户名放入session中,之后取出来,放入钩子函数,以后访问的视图函数中可直接取出来使用 uname = session.get('uname') print(uname) if uname: g.user = uname @app.context_processor def context_processor(): if hasattr(g,'user'): return {"current_user":g.user} else: return {} if __name__ == '__main__': app.run(debug=True)
errorhandler详解
需要注意几点:
在errorhandler装饰的钩子函数下,记得要返回相应的状态码。
在errorhandler装饰的钩子函数中,必须要写一个参数,来接收错误的信息,如果没有参数,就会直接报错。
使用flask.abort可以手动的抛出相应的错误,比如开发者在发现参数不正确的时候可以自己手动的抛出一个400错误。
常见的500错误处理:
from flask import Flask,g,render_template,abort app =Flask(__name__) @app.route('/') def index(): print(g.uname) return 'Hello!' @app.errorhandler(500) def server_error(error): # server_error() takes 0 positional arguments but 1 was given return render_template('500.html'),500 # 状态码虽然可以不写,但是推荐写上,这样可以告诉服务器是哪个错误 # return render_template('500.html') if __name__ =="__main__": # app.run(debug=True) app.run()
常见404错误处理:
from flask import Flask,g,render_template,abort app =Flask(__name__) @app.route('/') def index(): print(g.uname) return 'Hello!' @app.errorhandler(404) def server_error(error): return render_template('404.html'),404 if __name__ =="__main__": # app.run(debug=True) app.run()
Flask中的abort函数可以手动的抛出相应的错误(如400)
from flask import Flask,g,render_template,abort app =Flask(__name__) @app.route('/') def index(): print(g.uname) return 'Hello!' @app.errorhandler(404) def server_error(error): return render_template('404.html'),404 @app.route('/home/') def home(): abort(404) if __name__ =="__main__": # app.run(debug=True) app.run()
新年快乐!!!!!!!!!!!!!!2023年一定要更上一层楼!!!!!!!!