前言
Flask框架做爲一個python極簡化的web框架,它不像Django那樣的重型,很是適合快速開發一些小型的應用。本人用flask開發了幾個項目以後,慢慢研究flask底層的一些原理,開始一步步總結flask框架的使用方法以及設計原理。共勉!html
Flask框架簡介
-
基於Werkzeug工具箱編寫的輕量級Web開發框架,主要面向需求簡單的小應用;python
-
自己至關於一個內核,其餘幾乎全部的功能都須要用第三方的擴展來實現;web
-
核心是Werkzeug和Jinja2(路由模塊和模板引擎);shell
安裝環境
- 安裝Flask和全部可能相關依賴的包:
將全部相關的包放置在一個txt文件,如:requires.txt,內容以下:json
alembic==0.9.4 amqp==2.2.2 billiard==3.5.0.3 celery==4.1.0 certifi==2017.7.27.1 chardet==3.0.4 Flask==0.10.1 Flask-Migrate==2.1.0 Flask-Script==2.0.5 Flask-Session==0.3.1 Flask-SQLAlchemy==2.2 Flask-WTF==0.14.2 Jinja2==2.9.6 kombu==4.1.0 Mako==1.0.7
- 建立一個python新的虛擬環境,執行安裝:
可參考:http://www.cnblogs.com/cwp-bg/p/7701231.htmlflask
pip install -r requires.txt
建立一個簡單的應用程序
from flask import Flask app = Flask(__name__) # 裝飾器的做用是將路由映射到視圖函數index @app.route('/') def index(): return 'ok' if __name__ == '__main__': app.run()
執行啓動後咱們在瀏覽器輸入:http://127.0.0.1:5000就能夠訪問咱們剛剛創建的網站了,就這麼方便!api
- app初始化簡介
# Flask實例的源碼: class Flask(_PackageBoundObject): def __init__(self, import_name, # 指定應用的名字和工程目錄,默認爲__name__ static_path=None, # 是靜態文件存放的路徑,會賦值給static_url_path參數 static_url_path=None, # 設置靜態文件路由的前綴,默認爲「/static」 static_folder='static', # 靜態文件的存放目錄, 默認值爲"static" template_folder='templates', # 模板文件的存放目錄,默認值爲"templates" instance_path=None, # 設置配置文件的路徑,在instance_relative_config=True狀況下生效 instance_relative_config=False # 設置爲True表示配置文件相對於實例路徑而不是根路徑 root_path=None) # # 應用程序的根路徑
- 運行測試app程序
app.run(host=None, # 設置ip,默認127.0.0.1 port=None, # 設置端口,默認5000 debug=None) # 設置是否開啓調試,默認false
app的配置參數詳解
flask實例化後會加載默認的配置參數,咱們也能夠手動設置參數更新默認的配置,經常使用的參數選項有:瀏覽器
DEBUG:是否啓用debug模式,默認false。 TESTING :啓用/禁止測試模式 SECRET_KEY :密鑰,在啓用session等很重要 SESSION_COOKIE_NAME :設置保存的session在 cookie 的名稱 SESSION_COOKIE_DOMAIN:設置會話的域,默認是當前的服務器,由於Session是一個全局的變量,可能應用在多個app中;設置這個參數必須設置SERVER_NAME,不然報錯 PERMANENT_SESSION_LIFETIME:session失效時間,做爲一個 datetime.timedelta 對象,也能夠用秒錶示; LOGGER_NAME:日誌記錄器的名稱,默認__name__; SERVER_NAME:服務器的名稱以及端口,須要它爲了支持子域名 (如: 'myapp.dev:5000') MAX_CONTENT_LENGTH:設置一個請求所容許的最大的上傳數據量,單位字節; SEND_FILE_MAX_AGE_DEFAULT: 設置調用send_file發送文件的緩存時間; TRAP_HTTP_EXCEPTIONS:若是這個值被設置爲 True , Flask 不會執行 HTTP 異常的錯誤處理, 而是像對待其它異常同樣,經過異常棧讓它冒泡; PREFERRED_URL_SCHEME:設置URL 模式用於 URL 生成。若是沒有設置 URL 模式,默認將爲 http 。 JSON_AS_ASCII:默認狀況下 Flask 序列化對象成 ascii 編碼的 JSON。 若是不對該配置項就行設置的話,Flask 將不會編碼成 ASCII 保持字符串原樣,而且返回 unicode 字符串。jsonfiy 會自動按照 utf-8 進行編碼而且傳輸。 JSON_SORT_KEYS:默認狀況下 Flask 將會依鍵值順序的方式序列化 JSON。 這樣作是爲了確保字典哈希種子的獨立性,返回值將會一致不會形成 額外的 HTTP 緩存。經過改變這個變量能夠重載默認行爲。 這是不推薦也許會帶來緩存消耗的性能問題。 JSONIFY_PRETTYPRINT_REGULAR:若是設置成 True (默認下),jsonify 響應對象將會完美地打印。
加載配置文件的方法
- 經過加載文件設置參數
app.config.from_pyfile("./config.cfg") # 指定參數的路徑,內容按行書寫,配置文件放置在與app的同目錄下 def from_pyfile(self, filename, silent=False): filename = os.path.join(self.root_path, filename) pass
- 經過類設置參數
注意全部的參數必須大寫,不然無效。緩存
class Config(object): # 該類能夠定義在一個py文件中而後導入py文件 """配置參數""" DEBUG = True app.config.from_object(Config)
- 經過json格式的文件配置
# config.json { 'DEBUG' = True } app.config.from_json('config.json') # 配置文件放置在與app的同目錄下
- 直接操做app.config對象進行設置
app.config["DEBUG"] = True 或者 app.config.update({ "DEBUG":True, })
獲取配置參數的方法
app.config.get("DEBUG") 或者 current_app.config.get("DEBUG")
定義視圖函數
# 使用methods參數設置 @app.route('/',methods=["POST","GET"]) def index(): return 'ok'
route裝飾器會將其裝飾的視圖函數註冊到app的視圖函數集中,其主要有三個參數:ruby
rule:api路由,如:'/','/index'等; methods:設置容許的請求方式,如:'POST','GET'等,若是不設置,默認是GET方法; endpoint:視圖函數的標識符,是請求用來尋找對應的視圖函數的鍵,默認是視圖函數的名字。
注意點
-
相同的路由和請求方式,先定義的覆蓋後定義的,若是請求方式不一樣則不會覆蓋;能夠對不一樣的方式請求的分開寫視圖函數,但視圖函數必定不能相同;
-
同一個視圖函數加了多個路由,不管哪個均可以訪問到視圖;經過加多層裝飾器實現;
-
默認的請求方式爲get;能夠同時設置容許get和post請求訪問;
@app.route('/test',methods=["POST","GET"]) @app.route('/',methods=["POST","GET"]) def index(): return 'ok'
路由分發
- 步驟:經過程序實例的route裝飾器實現;route裝飾器內部會調用add_url_route()方法建立一個Rule對象,將該視圖函數的標識符和Rule對象做爲鍵值對加入到app的url_map中。
# 源碼 def route(self, rule, **options): def decorator(f): endpoint = options.pop('endpoint', None) self.add_url_rule(rule, endpoint, f, **options) return f return decorator
路由參數轉換器
flask容許將參數放置在路由中,經過路由轉換器來提取參數。
- 默認的參數轉換器
# 將路由轉化爲int類型的參數 @app.route('/user/<int:id>') def hello_itcast(id): return 'ok %d' %id
<>這種形式寫法就是轉換器,有int,float,path,default,uuid等幾種;
int : 提取整形 float: 提取浮點數 path: 提取路徑,包括/ string:提取字符串 default:即不寫類型<id>,除了/以外,默認是字符串 uuid:接受 UUID 字符串
- url的規則細節
-
若是url規則以/結尾,請求url沒有斜線,則引導到有斜線的頁面;
-
若是url規則結尾沒有斜線,請求帶有斜線,則找不到頁面;
獲取請求數據
# 導入請求對象request,該對象保存了一切請求的信息 from flask import request request.args:獲取路徑請求的參數,返回一個字典; request.form:獲取表單數據; request.values:包含from和args的所有內容; request.cookies:獲取cookie獲得一個dict; request.data:獲取數據做爲字符串存於此; request.headers:獲取請求頭; request.files:獲取上傳的文件;
返回響應數據
在視圖函數中返回的數據默認是一個三個元素的元組,分別表示返回的數據body,返回狀態碼和添加頭部信息。
@app.route('/') def index(): return 'ok',200,[("a", "b")] # 列表 # return 'ok',200,{"a":"b"} # 字典 # return 'ok',"666 hhhh",{"a":"b"} # 狀態碼能夠隨便,不會報錯
也可使用make_response()返回,其會直接建立一個response對象。
@app.route('/') def test(): return make_response('ok',200,{'a':'b'})
自定義異常處理
全部自定義的異常處理函數會加載到app對象的error_handler_spec屬性中保存。
@app.errorhandler(404) # number表示自定義的狀態碼 def handle_errer(errer): return errer # 表示錯誤的信息 # 定義好後,當使用abort函數時,會自動調用這個處理函數;
設置cookie和session
- 設置coookie
response.set_cookie(key,value,max_age=10) # 設置cookie的鍵和值,過時時間
# 能夠直接設置 response.header["Set-Cookie] = value # 獲取cookie response.cookie.get(key) # 刪除cookie response.delete_cookie(key) # 設置過時時間
- session須要配置secret_key參數
import flask import session # 設置加密的密匙 app.config["SECRET_KEY"] = 「password」 name = session.get("xx") # 獲取session中的數據 session.values() # 獲取session中的全部鍵的值 session.keys() # 獲取session中的全部鍵 session.items() # 獲取session中的全部鍵值對
session默認保存在cookie中;經過加密的方式來確保session不被更改;
參考
- https://dormousehole.readthedocs.io/en/latest