Flask框架知識系列之一

1,Flask框架的誕生:

Flask誕生于2010年,是Armin ronacher(人名)用Python語言基于Werkzeug工具箱編寫的輕量級Web開發框架。它主要面向需求簡單的小應用。

Flask本身相當于一個內核,其他幾乎所有的功能都要用到擴展(郵件擴展Flask-Mail,用戶認證Flask-Login),都需要用第三方的擴展來實現。比如可以用Flask-extension加入ORM、窗體驗證工具,文件上傳、身份驗證等。Flask沒有默認使用的數據庫,你可以選擇MySQL,也可以用NoSQL。其 WSGI 工具箱采用 Werkzeug(路由模塊) ,模板引擎則使用 Jinja2 。

可以說Flask框架的核心就是Werkzeug和Jinja2。

Python最出名的框架要數Django,此外還有Flask、Tornado等框架。
雖然Flask不是最出名的框架,但是Flask應該算是最靈活的框架之一,這也是Flask受到廣大開發者喜愛的原因。

2,Flask部分擴展包:

Flask-SQLalchemy:操作數據庫;
Flask-migrate:管理遷移數據庫;
Flask-Mail:郵件;
Flask-WTF:表單;
Flask-Bable:提供國際化和本地化支持,翻譯;
Flask-script:插入腳本;
Flask-Login:認證用戶狀態;
Flask-OpenID:認證;
Flask-RESTful:開發REST API的工具;
Flask-Bootstrap:集成前端Twitter Bootstrap框架;
Flask-Moment:本地化日期和時間;

3,Flask參考網站

中文文檔(http://docs.jinkan.org/docs/flask/

英文文檔(http://flask.pocoo.org/docs/0.11/

4,第一個Hello Flask程序

Flask程序運行過程:

所有Flask程序必須有一個程序實例。

Flask調用視圖函數后,會將視圖函數的返回值作為響應的內容,返回給客戶端。
一般情況下,響應內容主要是字符串和狀態碼。

當客戶端想要獲取資源時,一般會通過瀏覽器發起HTTP請求。
此時,Web服務器使用WSGI(Web Server Gateway Interface)協議,把來自客戶端的所有請求都交給Flask程序實例,程序實例使用Werkzeug來做路由分發(URL請求和視圖函數之間的對應關系)。
根據每個URL請求,找到具體的視圖函數。
在Flask程序中,路由的實現一般是通過程序實例的裝飾器實現。
通過調用視圖函數,獲取到數據后,把數據傳入HTML模板文件中,模板引擎負責渲染HTTP響應數據,然后由Flask返回響應數據給瀏覽器,最后瀏覽器處理返回的結果顯示給客戶端。

示例:


#導入Flask類
from flask import Flask

#Flask函數接收一個參數name,它會指向程序所在的模塊
'''
注意:name可以傳入的參數:
1,字符串:‘hello’,但是‘abc’,不行,因為abc是python內置的模塊
2,__name__

不可以插入的參數
1,python內置的模塊,re,urllib,abc等
2,數字
'''

app = Flask(__name__)

#裝飾器的作用是將路由映射到視圖函數index
@app.route('/')
def index():
    return 'Hello Flask'
    
#Flask應用程序實例的run方法啟動WEB服務器
if __name__ == '__main__':
    app.run()

5,默認的URL和正則URL

@app.route('<URL>')中URL顯式支持string、int、float、path 4種類型,隱式支持正則

5.1默認的url

分析源碼(在routing.py文件中,大概1092行中)發現url支持以下幾種類型

DEFAULT_CONVERTERS = {
    'default':          UnicodeConverter,
    'string':           UnicodeConverter,
    'any':              AnyConverter,
    'path':             PathConverter,
    'int':              IntegerConverter,
    'float':            FloatConverter,
    'uuid':             UUIDConverter,
}

5.2正則URL的實現

第一步,寫正則類,繼承BaseConverter,將匹配到的值設置為regex的值就可以了

class RegexUrl(BaseConverter):
    def __init__(self, url_map, *args):
        super(RegexUrl, self).__init__(url_map)
        self.regex = args[0]

第二步,把正則類賦值給我們定義的正則規則

app.url_map.converters['re'] = RegexUrl

第三步,在URL中使用正則

@app.route('/regex/<re("[a-z]{3}"):id>')
def regex(id):
    return 'id:%s'%id

6,Flask中鉤子的理解和應用

鉤子是通過裝飾器的形式實現的,支持以下四種

  1. before_first_request:在處理第一個請求前運行
  2. before_request:在每次請求前運行
  3. after_request:如果沒有未處理的異常拋出,在每次請求后運行
  4. teardown_request:即使有未處理的異常拋出,在每次請求后運行

應用:

@api.after_request
def after_request(response):
    """設置默認的響應報文格式為application/json"""
    # 如果響應報文response的Content-Type是以text開頭,則將其改為默認的json類型
    if response.headers.get("Content-Type").startswith("text"):
        response.headers["Content-Type"] = "application/json"
return response

7,自定義過濾器的步驟如下:

第一步:先定義自定義過濾器函數

def count_substring(string, substring):
    return string.count(substring)

第二步:注冊自己定義的過濾器

app.jinja_env.filters['count_substring'] = count_substring

第三步:最后在模板文件html中直接使用注冊時的鍵名

{#前面的作為原字符串string,傳入的作為子字符串substring#}
{{ 'A long long long long long  long longabc string ' | count_substring('long') }}<br/>

8,什么是Werkzeug?

Werkzeug是WSGI協議層工具集。
WSGI本身是一個用來確保你的web應用能夠與webserver進行對話,
更重要的是,確保web應用之間能夠一起配合工作的協議或約定。

在沒有Werkzeug幫助下,用WSGI實現的一個基本“Hello World”應用看起來是這樣的:

def application(environ, start_response):  
    start_response(‘200 OK’, [(‘Content-Type’, ‘text/plain’)])  
    return [‘Hello World!’]  

WSGI應用是你可以調用、傳遞一個environ字典和一個start_response函數的東西。
environ包含所有的傳入信息,start_response函數可以用來指示response的開始。

使用Werkzeug之后,你將不再需要直接處理被提交上來的請求(request)和應答(response)對象。
請求數據獲取environ對象,并允許你以一種良好的方式訪問environ中的數據。
response對象本身也是一個WSGI應用,提供了很多友好的創建response的方法。
下面的代碼演示了如何編寫帶有response對象的應用:

from werkzeug.wrappers import Response  
def application(environ, start_response):  
    response = Response(‘Hello World!’, mimetype=‘text/plain’)  
    return response(environ, start_response)  

9,flask-script指令第三方擴展

第一種——創建Command子類

Command子類必須定義一個run方法;
舉例:創建Hello命令,并將Hello命令加入Manager實例


from flask_script import Manager  
from flask_script import Command  
from debug import app  
  
manager = Manager(app)  
  
class Hello(Command):  
    'hello world'  
    def run(self):  
        print 'hello world'  
  
manager.add_command('hello', Hello())  

def make_shell_context():
    return dict(app = app, db=db)

manager.add_command("shell",Shell(make_context=make_shell_context))
  
if __name__ == '__main__':  
    manager.run()

第二種——使用Command實例的@command修飾符

from flask_script import Manager  
from debug import app  
  
manager = Manager(app)  
 
@manager.command  
def hello():  
    'hello world'  
    print 'hello world'  
  
if __name__ == '__main__':  
    manager.run()

第三種——使用Command實例的@option修飾符

復雜情況下,建議使用@option;
可以有多個@option選項參數

10,請求上下文和應用上下文的區別

current_app、g就是應用上下文
requests、session就是請求上下文

手動創建上下文的兩種方法:
with app.app_context()
app = current_app._get_current_object()

11,Flask特有的變量和函數

config

你可以從模板中直接訪問Flask當前的config對象:
app.config['SQLALCHEMY_DATABASE_URI'] = 'mysql://root:xiaoke@127.0.0.1:3306/test'

request:

就是flask中代表當前請求的request對象:
http://127.0.0.1

session

為Flask的session對象

注意:

flask中有三個session:
第一個:數據庫中的session,例如:db.session.add()
第二個:在flask_session擴展中的session,使用:from flask_session import Session,使用第三方擴展的session可以把信息存儲在服務器中,客戶端瀏覽器中只存儲sessionid
第三個:flask自帶的session,是一個請求上下文, 使用:from flask import session。自帶的session把信息加密后都存儲在客戶端的瀏覽器cookie中

url_for()

url_for會根據傳入的路由器函數名,返回該路由對應的URL,在模板中始終使用url_for()就可以安全的修改路由綁定的URL,則不比擔心模板中渲染出錯的鏈接:

{ {url_for('home')} }

如果我們定義的路由URL是帶有參數的,則可以把它們作為關鍵字參數傳入url_for(),Flask 會把他們填充進最終生成的URL中:

{ { url_for('post', post_id=1)} }
/post/1

get_flashed_messages()

這個函數會返回之前在flask中通過flash()傳入的消息的列表,
flash函數的作用很簡單,可以把由Python字符串表示的消息加入一個消息隊列中,再使用get_flashed_messages()函數取出它們并消費掉:

{ %for message in get_flashed_messages()% }
    message
{ %endfor% }
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 228,443評論 6 532
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 98,530評論 3 416
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 176,407評論 0 375
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 62,981評論 1 312
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 71,759評論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,204評論 1 324
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,263評論 3 441
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,415評論 0 288
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 48,955評論 1 336
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 40,782評論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 42,983評論 1 369
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,528評論 5 359
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,222評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,650評論 0 26
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,892評論 1 286
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,675評論 3 392
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 47,967評論 2 374

推薦閱讀更多精彩內容