1. 程式人生 > >flask使用基礎

flask使用基礎

1、安裝

  pip install Flask

  基本依賴庫:

    jinja2:實現對模板的處理

    werkzeug:本質是socket伺服器,用於接收http請求,並對請求進行預處理,然後觸發Flaks框架,開發人員基於Flask框架提供的功能對請求進行相應的處理並返回給使用者。

 2、建立核心物件

  from flask import Flask

  app = Flask(__name__)

  值得注意的是,這裡的__name__,一般是模組名或者包名,如果是單個模組,這裡直接寫__name__肯定是沒有問題的。

  但是如果使用的是軟體包,官方建議的是這裡使用硬編碼來傳入包名。

  還可以直接在包的__init__.py檔案中穿件方法來例項化我們的app,這樣傳入的__name__名稱也是包名。

  def instance_app():

    app = Flask(__name__)

    ...

    return app

  然後在入口檔案中引入instance_app

  __name__的名稱決定了專案的根目錄。專案中的靜態檔案,模板檔案等都是通過根目錄路徑在尋找的。

  預設情況下,靜態檔案時放在根目錄下的static資料夾中的。但是如果我們修改了靜態資料夾的位置或者名稱,可以在例項化Flaks核心物件的時候指定自定義路徑

  

  如上圖,預設情況下,Flask例項化可以接受靜態檔案,模板路徑等等,如在根目錄下新建資料夾static12,然後上傳圖片timg.jpg

  然後在例項化Flaks核心物件的時候傳入自定義靜態檔案地址

  app = Flask(__name__, static_folder='static12', static_url_path='static12')即可

  static_folder:是我們自定義的靜態資料夾相對於根目錄的位置。

  static_url_path:用於為靜態檔案指定不同的路徑,static_url_path+filename 整理構成了靜態檔案的訪問路徑,預設情況下static_url_path和static_folder是一樣的,所以上面的例子,也可以省略掉static_url_path

  從下面的原始碼可以看到,定義了_get_static_url_path()函式用來獲取static_url_path,如果我們配置了static_url_path,直接取我們配置的,如果static_url_pathNone,回去取static_folder的值。

  

  最後,呼叫Flask的add_url_rule函式配置靜態檔案訪問路徑,最終執行靜態檔案訪問的是view_func即send_static_file()

  

   所以,我們可以重寫send_static_file()函式,可以用來判斷是否有許可權訪問此檔案等

   

2、啟動程式

  from apps import instance_app(這裡apps是我的應用包名)

  app = instance_app()

  if __name__=="__main__":

    app.run(host='0.0.0.0', port=80, thread=True)

  1)我們為什麼要在入口函式中新增__name__=='__main__'判斷?

    原因1:加入__name__=="__main__" 確保我們的run()函式只有在當前指令碼被python直譯器直接執行的時候才會執行,而被其他模組import的時候不會被執行

    原因2:開發環境下,我們啟動的是flask自帶的一個非常簡單的伺服器,但是在部署到生產環境中時,用的是uwsgi和nginx組合來部署專案,nginx作為前置伺服器用來接收我們瀏覽器發來的請求,轉發給uwsgi,

        在生產環境中,並不是我們手動的去啟動我們的模組,而是通過uwsgi來載入我們的模組來啟動程式碼。

        所以如果在生產環境中,我們的入口檔案就不再是入口檔案了,解了if判斷後,app.run就不會去執行。

        但是如果不加if判斷,生產環境一旦載入了我們的入口檔案後,app.run()就會被執行,這樣就會導致我們在已經擁有了uwsgi作為外部伺服器的同時,又啟動了內部伺服器,這種情況是不可取的。

3、配置路由

  使用核心物件的route()裝飾器把函式繫結到對應的url上

  @app.route("/hello")  # 無參

  def say_hello():

    return "hello"

 

  @app.route("/hello/<name>")  # 有參

  def say_hello1(name)

    return "hello"+name

  

  flask的url規則基於werkzeug的路由模組。這個模組背後的思想是基於Apache和更早的http伺服器主張的先例,保證優雅且唯一的url。

  以下面兩個規則為例:

  @app.route("/hello")

  def say_hello():

    return "hello"

  

  @app.route("/hello1/")

  def say_hello1():

    return "hello1"

   

  上面兩種情況看起來url很相似,一個加斜線,一個不加斜線,但是他們結尾的斜線在url定義中不同

  第一個結尾不帶斜線的,如果訪問url後面加上斜線,會返回404

  第二個結尾帶斜線的,如果訪問url後面忘了加上斜線,Flask在收到這個請求後,會將請求重定向到到斜線的url上面去,所以我們看到第二種情況中,輸入不到斜線的url訪問目標函式,瀏覽器請求了兩次,第一次返回301,即告訴瀏覽器,需要重定向。

 

3、生成url

  通過url_for()來給指定的函式構造url

  1)它接收函式名作為第一個引數

    url_for("login")  #  /login

  2)它也接收對應url規則的變數部分的命名引數,如一個url需要引數username

    url_for("login", username="john")  # /login/john

  3)對於未知變數部分,會新增到url末尾作為查詢引數

    url_for("login", next='/')  # /login?next=/

  4)使用反向構建url的意義:

    a)易於維護

    b)url構建會自動轉義特殊字元和Unicode資料,省去很多麻煩

    c)如果我們的應用不是在根路徑下面,url_for會妥善的處理這個問題。

4、HTTP方法

  通過route()裝飾器的methods引數可以定義該方法介紹哪些請求

  @app.route("/login", methods=['GET', 'POST'])

  from flask import request

  def login():

    if request.method=='POST':

      pass

5、模板渲染

  flask配備了jinja2模板引擎,我們可以使用render_template方法來渲染模板。

  from flask import render_template

  @app.route("/hello/<name>")

  def hello(name):

    return render_template("index.html", name=name)

 

6、關於響應

  flask轉換響應物件的邏輯如下:

  1)如果返回的是一個合法的響應物件,它會從檢視直接返回

  2)如果返回的是一個字串,它會被轉換為該字串為主體的,狀態碼為200,MIME型別為‘text/html’的響應物件。

  3)如果返回的是一個元組,且元組中的元素可以提供額外的資訊。這樣的元組必須是(response,status,header)的形式。header作為額外的訊息頭標誌,可以是一個列表或字典。

  如果我們想要在視圖裡操作響應物件,可以使用make_response()函式

  如我們有這樣一個函式

  @app.errorhandler(404)

  def not_found(error):

    return render_template("error.html",404)

  我們只需要將返回值表示式傳遞給make_response()函式,獲取結果物件,並修改,然後返回

  from flask import make_response

  @app.errorhandler(404)

  def not_found(error):

    resp = make_response(render_remplate("error.html"),404)

    resp.headers[X-something] = 'A-value'

    return resp

 

 

參考:http://docs.jinkan.org/docs/flask