• Flask從入門到入土(二)——請求响应與Flask扩展


    ————————————————————————————————————————————————————————————

    一.程序和請求上下文

      Flask從客戶端收到請求時,要讓視圖函數能訪問一些對象,這樣才能處理請求。請求對象就是一個很好的例子,它封裝了客戶端發送的Http請求。

      要想讓視圖函數能夠訪問請求對象,一個顯而易見的方式是將其作爲參數傳入視圖函數,不過這會導致程序中的每個視圖函數都增加一個參數。除了訪問請求對象,如果視圖函數在處理請求時還要訪問其他對象,情況會變得糟糕。

      爲了避免大量可有可無的參數,Flask使用了上下文臨時把某些對象變爲全局可訪問。有類上下文,就可以寫出下面的函數視圖。

     1 from flask import Flask
     2 from flask import request
     3 app = Flask(__name__)
     4 
     5 @app.route('/')
     6 def index():
     7     user_agent = request.headers.get('User-Agent')
     8     return '<h3>Your browser is %s</h3>' %user_agent
     9 
    10 if __name__=='__main__':
    11     app.run()

      在Flask中有兩種上下文:程序上下文和請求上下文。

      程序上下文:       current_app     當前激活程序的程序實例

              g                      處理請求時臨時用作臨時存儲對象。每次請求都會重置這個變量

      請求上下文:  request    請求對象,封裝了客戶端發出的HTTP請求中的內容

              session    用戶會話,用與存儲請求之間需要“記住”的值的詞典

      Flask在發送請求之前激活程序和請求上下文,請求處理完成後再將其刪除。

      下面這個Python shell會話演示了程序上下文的使用方法:

      >>>from hello import app

      >>>from flask import current_app

      >>> current_app.name

      Traceback (most recent call last):

      ...

      RuntimeError:working outside of application context

      >>> app_ctx = app.app_context()

      >>> app_ctx.push()

      >>> current_app.name

      'hello'

      >>> app_ctx.pop() 

      在沒有激活程序上下文之前就調用current_app.name會導致錯誤,但推送完上下文之後就可以調用了。

      注意:在程序實例中調用app.app_context()可獲得一個程序上下文。

    ————————————————————————————————————————————————————————————

    二.請求調度

      程序收到客戶端發來的請求時,要找到處理該請求的視圖函數。爲了完成這個任務,Flask會在程序的URL映射中查找請求的URL。URL映射是URL和視圖函數之間的對應關系。Flask使用app.route修飾器或者非修飾器形式的app.add_url_rule()生成映射。

      URL映射中的HEAD,Options,GET是請求方法,由路由進行處理。Flask爲每一個URL都指定了請求方法,這樣不同的請求方法發送到相同的URL上時,會使用不同的視圖函數進行處理。HEAD和OPTIONS方法由Flask自動處理,其他都書GET方法。

    三.請求鉤子

      有時在處理請求之前或之後執行代碼會很有用。例如,在請求開始時,我們可能需要創建數據庫連接或者認證發起請求的用戶。爲了避免在每個視圖中都使用重復的代碼,Flask提供了注冊通用函數的功能,注冊函數可在請求被分發到視圖函數之前或之後調用。

      請求鉤子使用修飾器實現,Flask支持以下4種鉤子。

      *before_first_request : 注冊一個函數,在處理第一個請求之前運行。

      *before_request         : 注冊一個函數,在每次請求之前運行。

      *after_request            : 注冊一個函數,如果沒有處理異常的拋出,在每次請求之後運行。

      *teardown_request  : 注冊一個函數,即使有未處理的異常拋出,也在每次請求之後運行。  

      在請求鉤子函數和視圖函數之間共享數據一般使用上下文全局變量g。例如,before_request處理程序可以從數據庫中加載已登錄用戶,並將其保存到g.user中。隨後調用視圖函數時,視圖函數再使用g.user獲取用戶。

    四.响应

      Flask調用視圖函數後,會將其返回值作爲响应的內容。大多數情況下,响应就是一個簡單的字符串,作爲HTML頁面送回客戶端。

    但HTTP協議需要的不僅是作爲請求响应的字符串。HTTP响应中一個很重要的部分是狀態碼,Flask默認設置是200,這個代碼表明請求已經被成功處理。

      Flask還可以返回Response對象。make_response()函數可以接受1個,2個或3個參數。並返回一個Response對象。有時我們需要在視圖函數中進行這種轉換,然後在響應對象上調用各種方法,進一步設置響應。

     1 from flask import Flask
     2 from flask import make_response
     3 
     4 app = Flask(__name__)
     5 
     6 @app.route('/')
     7 def index():
     8     response = make_response('<h1>This is document</h1>')
     9     response.set_cookie('answer','yooooooo~')
    10     return response
    11 
    12 if __name__=='__main__':
    13     app.run()

      有一種名爲重定向的特殊响应類型。這種响应沒有頁面文檔,只告訴瀏覽器一個新地址用以加載新頁面。重定向經常在Web表單中使用。狀態碼一般是302,指向的地址由Location首部提供。重定向响应可以使用3個形式的返回值生成,也可以在Response對象中設定。不過,由於使用頻繁,Flask提供了redirect()輔助函數,用於生成這種響應:

     1 from flask import Flask
     2 from flask import redirect
     3 
     4 app = Flask(__name__)
     5 
     6 @app.route('/')
     7 def index():
     8     return redirect('http://www.baidu.com')
     9 
    10 if __name__=='__main__':
    11     app.run()

        

      重定向至http://www.baidu.com

      還有一種特殊响应由abort函數生成,用於處理錯誤。如果URL中動態參數ID對應用戶不存在,就返回狀態碼404: 

     1 from flask import Flask
     2 from flask import abort
     3 
     4 app = Flask(__name__)
     5 
     6 @app.route('/')
     7 def index():
     8     return 'hello'
     9 
    10 @app.route('/user/<id>')
    11 def user(id):
    12     user = load_user(id)
    13     if not user:
    14         abort(404)
    15     return 'hello,%s' %user.name
    16 
    17 if __name__=='__main__':
    18     app.run()

    五.Flask扩展 

     1 from flask import Flask
     2 
     3 app = Flask(__name__)
     4 
     5 @app.route('/')
     6 def index():
     7     return '<h7>hello</h7>'
     8 
     9 if __name__=='__main__':
    10     app.run(host='192.168.1.8')

      之後便可在統一網絡下使用http://192.168.1.8:5000 來進行訪問。

     

       

  • 相关阅读:
    计算机知识
    试题:论需求分析方法及应用
    试题:论信息系统开发方法及应用
    爬虫数据存储——安装docker和ElasticSearch(基于Centos7)
    go并发版爬虫
    go单任务版爬虫
    可变类型与不可变类型
    基本数据类型内置方法
    @submit.native.prevent作用
    获取当月第一天,今天的日期的方法
  • 原文地址:https://www.cnblogs.com/LexMoon/p/Flask_2.html
Copyright © 2020-2023  润新知