目錄
請求擴展
before_request
類似於django中的process_request,在收到請求之后,進入視圖函數之前,進行一些數據或者怎樣的處理
- 可寫多個before_request函數
- 從上往下執行的
- 一旦有返回值,請求的視圖函數不會執行,已經剩下的before_request不會執行
from flask import Flask,render_template,request,redirect,session,url_for
app = Flask(__name__)
app.debug = True
app.secret_key = "123#234"
USERS = {
1:{"name":"老大", "age":19,"gender":"男", "resume":"言語措辭間都能體會到今日頭條的謹小慎微,生怕再出現任何問題……."},
2:{"name":"老二", "age":18,"gender":"女", "resume":"當打開這款APP之后,就會發現這跟已經“死”去的內涵段子簡直是一模一樣。更厲害的地方是,它還支持用用戶遷移內涵段子上的內容信息。"},
3:{"name":"老三", "age":17,"gender":"男", "resume":"如果狒狒會說人話,他肯定是在說:喂…你怎么只給我吃了一口就跑了呀,我還沒吃飽啊…喂喂喂…給我回來呀!哈哈哈"},
}
# 基於flask里請求擴展來做
@app.before_request
def process_request(*args, **kwargs):
# 驗證表示,任何地址請求都會先執行before_request,所以登錄驗證就可以在before_request里做用戶認證功能了
print("其他請求之前就執行了process_request")
# 4.訪問/login的時候還沒有登錄,就會一直重定向到登錄頁,所以就要設置個白名單,如果請求地址是/login,就返回None
if request.path == "/login":
return None
# 1.登錄驗證功能
user = session.get('user_info')
# 2.如果登錄信息正常,什么都不做,程序繼續其他執行
if user:
return None
# 3.如果登錄驗證不通過,就重定向到登錄頁面
return redirect("/login")
@app.route("/detail/<int:nid>", methods=['GET'])
def detail(nid):
detail_info = USERS.get(nid)
# 如果有值,就跳到詳情頁
return render_template("detail.html",info = detail_info)
@app.route("/index", methods=['GET'])
def index():
return render_template("index.html", user_dict=USERS)
@app.route("/login", methods=['GET', 'POST'], endpoint='l1')
def login():
if request.method =="GET":
return render_template("login.html")
else:
user = request.form.get("username")
pwd = request.form.get("password")
if user == "alex" and pwd =="123456":
session['user_info'] = user
return redirect("/index")
return render_template("login.html", **{"error":"用戶名和密碼錯誤"})
if __name__ == "__main__":
app.run()
after_request
類比django中間件中的process_response,每一個請求之后綁定一個函數,如果請求沒有異常
- 可以寫多個after_request函數
- 所有的after_request是從下往上執行,和before_request相反
- 無論 before_request有沒有返回值,我的after_request都會執行
- 必須接受response,而且必須返回response
from flask import Flask,render_template,request,redirect,session,url_for
app = Flask(__name__)
app.debug = True
app.secret_key = 'siuljskdjfs'
@app.before_request
def process_request1(*args,**kwargs):
print('process_request1 進來了')
@app.after_request
def process_response1(response):
print('process_response1 走了')
# after_request 必須返回 response
return response
# 視圖函數
@app.route('/index',methods=['GET'])
def index():
print('index函數')
return "Index"
if __name__ == '__main__':
app.run()
before_first_request
項目啟動后,接受到的第一個請求,會執行該函數,后面就不會在執行
比如:數據庫的連接,初始化操作
from flask import Flask,request
app = Flask(__name__)
app.debug = True
# 內部其實就有個判斷,初始值是FALSE,第一次執行后將值改變為True,以后判斷后就不執行了
@app.before_first_request
def before_first_request2():
print('before_first_request2')
if __name__ == '__main__':
app.run()
teardown_request
每一個請求之后綁定一個函數,即使遇到了異常 ,也不會終止函數的執行
- 這是e 是接收我服務器拋出的異常
- 無論我服務器有沒有錯誤,都會執行該函數
- 雖然能接收異常,但是沒有辦法處理異常
- 可以用來監控程序是否報錯,記錄日志
#如論有無異常都執行,如果沒有異常這個e就是None
@app.teardown_request
def ter(e):
# if e:
#logingh
# return "wo si l"
print("我拋異常")
errorhandler
定制錯誤信息:
- 參數的中值為錯誤碼
- 當服務器拋出對應狀態碼的異常,就會執行該函數
- 並且該函數可以處理異常,讓用戶無法感知,服務器錯誤
- 每一個錯誤碼,都需要一個對應的函數進行處理
from flask import Flask,render_template,request,redirect,session,url_for
app = Flask(__name__)
app.debug = True
app.secret_key = 'siuljskdjfs'
# 經常會出現url不存在的情況,一般會有錯誤信息
# 而這個錯誤信息也是可以進行定制的,根據錯誤碼定制錯誤信息方法如下:
@app.errorhandler(404)
def error_404(arg):
return "404錯誤了"
# 視圖函數
@app.route('/index',methods=['GET'])
def index():
print('index函數')
return "Index"
if __name__ == '__main__':
app.run()
template_global
模板中定制方法/定制模板方法:
from flask import Flask,request
app = Flask(__name__)
app.debug = True
# 這就是基於請求擴展的 定制模板方法
# 相對於在模板里定制了一個函數
@app.template_global()
def sb(a1, a2):
return a1 + a2
# 在HTML里調用的方式:{{sb(1,2)}}
if __name__ == '__main__':
app.run()
template_filter
過濾器
from flask import Flask,request
app = Flask(__name__)
app.debug = True
# 這就是基於請求擴展的 定制模板方法
@app.template_filter()
def db(a1, a2, a3):
return a1 + a2 + a3
#在HTML里調用的方式如下:
# {{ 1|db(2,3)} # 參數 a1 = 1,是第一個參數; a2=2 是第二個參數; a3=3 是第三個參數
if __name__ == '__main__':
app.run()