内容有:1、配置文件处理,2、路由系统,3、视图,4、请求,5、响应,6、模板渲染,7、session,8、flash,9、中间件,10特殊装饰器
一:一个简单知识点
通过路径构成的字符串1、动态导入模块2、找到类,3、字段4、字段的值
import importlib path = "settings.Foo" path_item = path.rsplit(".",maxsplit=1) # 1、通过importlib导入模块 module = importlib.import_module(path_item[0]) #2、通过getattr找到类 cls = getattr(module,path_item[1]) #3、通过dir找到类中的字段 for item in dir(cls): if item.isupper(): # 4、通过getattr获取字段的值 print(item,getattr(cls,item))
二:配置文件使用
from flask import Flask,render_template,request app = Flask(__name__,template_folder='templates') app.config.from_object("settings.Foo") @app.route("/login",methods=["GET","POST"]) def login(): if request.method == "GET": return render_template("login.html") return "ok" app.run()
settings中内容:
class Base(object): """存放共有的内容""" xx = True class Foo(Base): DEBUG = True TEST = True class Dev(Base): DEBUG = False
三:路由系统
1、endpoint
endpoint相当于Django里面的name,url的别名,用于反向生成url。url_for用于反向生成url。如果装饰器中没有endpoint参数,则默认的endpoint的值为函数名。
from flask import Flask,render_template,request,url_for @app.route("/login",methods=["GET","POST"],endpoint="login") def login(): if request.method == "GET": print(url_for("login")) return render_template("login.html") return "ok"
2、url_for
用于反向生成url
3、动态路由
不支持正则,需要用其他的方式实现
使用url_for反向生成动态路由需要往url_for中传递参数
@app.route('/user/<username>')
@app.route('/post/<int:post_id>')
@app.route('/post/<float:post_id>')
@app.route('/post/<path:path>')
@app.route('/login', methods=['GET', 'POST'])
from flask import Flask,render_template,request,url_for app = Flask(__name__,template_folder='templates') app.config.from_object("settings.Foo") @app.route("/login/<int:nid>",methods=["GET","POST"],endpoint="login") def login(nid): if request.method == "GET": print(nid) print(url_for("login",nid=2)) return render_template("login.html") return "ok" app.run()
四、请求相关数据
request.method
request.args
request.form
request.values
request.cookies
request.headers
request.path
request.full_path
request.script_root
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))
五、响应相关数据
return "字符串"
return render_template('html模板路径',**{})
return redirect('/index.html')
from flask import Flask,render_template,request,url_for,jsonify user_dic = {1:"wang",2:"zhang"} return jsonify(user_dic)
jsonify相当于在内部做了字符串的序列化,相当于json.dumps
如何响应返回的数据需要加上响应头时,通过make_response实现
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
六、模板渲染
1、列表,元组传到前端,前端的表示方式
<li>{{user_list[0]}}</li> <li>{{user_list[1]}}</li> <li>{{user_list.0}}</li> <li>{{user_list.1}}</li>
2、传递需要渲染的字符串
(1)
{{ txt|safe }}
context = {'txt':"<input type='text'/>"} @app.route("/index",methods=["GET","POST"]) def index(): return render_template("index.html",user_dict = USER_DICT,user_list = USER_LIST,**context)
(2)
context = {'txt':Markup("<input type='text'/>")} @app.route("/index",methods=["GET","POST"]) def index(): return render_template("index.html",user_dict = USER_DICT,user_list = USER_LIST,**context)
{{ txt }}
3、向前端传入函数
(1)手动自己传
def func(): return "hello" context = {'txt':Markup("<input type='text'/>"), 'func':func} @app.route("/index",methods=["GET","POST"]) def index(): return render_template("index.html",user_dict = USER_DICT,user_list = USER_LIST,**context)
{{func}} 表示函数本身 {{func()}} 表示函数的执行
(2)全局传递 @app.template_global() @app.template_filter()
@app.template_global() def add(a,b): return a + b
{{add(3,4)}} 不用传递,可以直接在前端写
@app.template_filter() def add(a,b,c): return a + b + c
{{1|add(3,4)}} 不用传递,可以直接在前端写
七:session
session在服务器端(程序中)的操作相当于对一个字典进行操作
当请求刚到来时,flask从cookie中获取session对应的值,并反序列化为一个字典放入内存中,以便视图函数进行处理。对它的操作就是增删改查。
@app.route("/s1",methods=["GET"]) def s1(): session["k1"] = "k1" session["k2"] = "k2" del session["k1"] return "ok"
当请求结束时,flask会读取内存中字典的值,进行序列化+加密,写入到用户cookie中。
八、flash
在session中存储的一个数据,读取后通过pop将数据移除,只能取一次数据。
@app.route("/p1",methods=["GET"]) def p1(): flash("临时数据") return "p1" @app.route("/p2",methods=["GET"]) def p2(): ret = get_flashed_messages() print(ret) return str(ret) @app.route("/pa1",methods=["GET"]) def pa1(): flash("错误1","err") flash("错误2","err") flash("错误3","err") flash("正确1","right") flash("正确2","right") return "ok" @app.route("/pa2",methods=["GET"]) def pa2(): ret = get_flashed_messages(category_filter=["err"]) print(ret) return str(ret)
九:中间件
在flask中中间件的使用不是很多,也不是很重要,主要是使用特殊装饰器完成相应的功能。
在接收到请求后才执行请求的__call__方法。
需求:完成一个功能,在执行__call__(一个函数)前执行一个操作,在__call__(一个函数)后执行一个操作。也就是在请求前执行一个操作,在请求后执行一个操作。
class MiddleWare(object): def __init__(self,old): self.old = old def __call__(self, *args, **kwargs): print("wsgi_app执行前执行的操作") ret = self.old(*args, **kwargs) print("wsgi_app执行后执行的操作") return ret app.wsgi_app = MiddleWare(app.wsgi_app) app.run()
十、特殊装饰器
1. before_request
2. after_request
示例:
from flask import Flask
app = Flask(__name__)
@app.before_request
def x1():
print('before:x1')
return '滚'
@app.before_request
def xx1():
print('before:xx1')
@app.after_request
def x2(response):
print('after:x2')
return response
@app.after_request
def xx2(response):
print('after:xx2')
return response
@app.route('/index')
def index():
print('index')
return "Index"
@app.route('/order')
def order():
print('order')
return "order"
if __name__ == '__main__':
app.run()
3. before_first_request
from flask import Flask
app = Flask(__name__)
@app.before_first_request
def x1():
print('123123')
@app.route('/index')
def index():
print('index')
return "Index"
@app.route('/order')
def order():
print('order')
return "order"
if __name__ == '__main__':
app.run()
4. template_global
5. template_filter
6. errorhandler
@app.errorhandler(404)
def not_found(arg):
print(arg)
return "没找到"