Flask进阶
Flask进阶
1.Flask中内置session
1.1 Flask中设置session需要secret_key
flask会将你的SessionID存放在客户端的Cookie中
from flask import session
app = Flask(__name__)
app.secret_key = "i am session" #这里只需要随机指定一个字符串即可
@app.route("/login", methods=["GET", "POST"])
def login():
if request.method == "POST":
if request.form["username"] == "root" and request.form["password"] == "root":
session["user"] = USER["username"] #设置session
return redirect("/student_list")
return render_template("login.html", msg="用户名密码错误")
return render_template("login.html", msg=None) # 如果前端Jinja2模板中使用了msg,这里就算是传递None也要出现msg
1.2 验证session
cookies 中 session 存储的是通过 secret_key 加密后的 key
@app.route("/student_list")
def student():
if session.get("user"): #session存在
return render_template("student_list.html", student=STUDENT_DICT)
return redirect("/login")
2.装饰器
2.1 装饰器
#@functools.wraps(fun)
def wrapper(fun):
@functools.wraps(fun)
def inner(*args,**kwargs):
return fun(*args,**kwargs)
return inner
2.2 应用
#1.装饰器写在route下面
@app.route('/index',endpoint="index")
@wrapper
def index():
return render_template("index.html",DATA_DIC=DATA_DIC)
print(index.__name__) #2.因为原来index=inner,装饰器加上@functools.wraps(fun)内部执行的还是inner函数,但名字改为index
2.3 上下文管理
使用with语句(with 对象 as a),默认会执行类中的__enter__()方法,将返回值返回给a,当with中的代码块执行完,会执行__exit__()方法
class Foo(object):
def __enter__(self):
return 123
def __exit__(self, exc_type, exc_val, exc_tb):
pass
obj = Foo()
with obj as f:
print(f)
文件句柄中,with语句执行完会自动关闭文件句柄,就是因为__exit__()方法中默认有close()方法
class Foo(object):
def __enter__(self):
self.f = open("1.txt","r")
return self.f
def __exit__(self, exc_type, exc_val, exc_tb):
self.close()
obj = Foo()
with obj as f:
print(f.read())
3.配置文件
3.1 基于全局变量
在生产时,通常使用localsettings和settings,localsettings中的配置是在本地使用的,项目部署时不用上传到服务器,这里结合git版本工具使用
1.先git init初始化自己的项目被git管理
2.vim .gitignore 文件中写入不需要上传至服务器的文件localsettings.py的文件路径
视图函数(使用app.config.from_obj导入配置文件settings.py):
from flask import Flask,Response,render_template
app = Flask(__name__,template_folder="templates",static_folder="static")
app.config.from_object("config.settings")
@app.route('/login')
def login():
return render_template("login.html")
if __name__ == '__main__':
app.run("127.0.0.1",5000,login)
config下的settings.py
try:
from .localsettings import *
except ImportError:
pass
config下的localsettings.py
DBA="xxx"
3.2 基于类
4. CBV
from flask import Flask,render_template,views
app = Flask(__name__)
def test1(func):
def inner(*args,**kwargs):
print("before1")
result = func(*args,**kwargs)
print("after1")
return result
return inner
def test2(func):
def inner(*args,**kwargs):
print("before2")
result = func(*args,**kwargs)
print("after2")
return result
return inner
class UserView(views.MethodView):
methods = ["get","post"]
decorators = [test1,test2] #定义装饰器
def get(self):
return "get"
def post(self):
return "post"
5. Flask中的中间件(特殊中间件)
before_request:相当于process_request,当返回None时,继续向下执行,返回真实值时,直接返回,不用继续向下执行
after_request:相当于process_response
5.1 单装饰器
from flask import Flask,render_template,request
app = Flask(__name__)
@app.before_request #在所有视图执行之前执行
def f1():
if request.path == "/login":
print("f1")
return
@app.after_request #在视图执行之后执行
def f2():
print("f2")
@app.route("/index")
def index(response): #此处需添加参数,为返回的response对象
print("index")
return render_template("index.html")
#打印结果:f1 index f2
5.2 多装饰器
from flask import Flask,render_template,request
app = Flask(__name__)
@app.before_request
def f1():
print("f1")
@app.before_request
def f2():
print("f2")
@app.after_request
def f3():
print("f3")
@app.after_request
def f4():
print("f4")
@app.route("/index")
def index():
print("index")
return render_template("index.html")
#打印结果:
f1 f2 index f4 f3