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