1. 程式人生 > >flask內容學習第二天

flask內容學習第二天

獲取用戶信息 RM def 構造 pan err 工作 code AS

異常的捕獲

技術分享圖片
 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)
View Code

註冊一個處理程序錯誤的裝飾器,當程序拋出指定錯誤狀態碼的時候會調用裝飾器所裝飾的方法(除了捕獲異常的狀態碼之外還可以捕獲指定的異常)

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)
View Code
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的使用

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)
cookie的設置

備註:

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)
session的設置

請求上下文(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)
View Code

通過使用Flask-Script擴展,我們可以在Flask服務器啟動的時候,通過命令行的方式傳入參數。而不僅僅通過app.run()方法中傳參,比如我們可以通過:

python hello.py runserver -host ip地址



flask內容學習第二天