flask文檔學習筆記1-快速入門

開始決定認真的在網上寫一些東西,主要緣由仍是在於但願能提高學習效果。雖然說python寫了有幾年,可是web後端框架的確沒怎麼接觸過,買了本狗書寥寥草草的過了一遍,發現不少東西仍是理解不深,真的是好記性不如爛筆頭,知識也要從基礎開始,退回來好好看看官方文檔,再去看狗書吧。
網上有翻譯好的官方文檔,基本是基於0.10.1版本翻譯的,和目前版本對比了一下,細節上仍是有一些不一樣(狗書也存在這個問題),因此仍是老老實實的看英文原版學習吧,目前的版本是0.12.2html

「微型」的含義

衆所周知,flask是一個使用Python開發的「微型」Web框架,文檔中特地強調了,所謂「微型」並不意味着Web應用的開發只能寫在一個Python文件裏,也不意味着flask自身功能不夠豐富。「微型」的目的在於,保持一個「簡單」而且「可擴展」的框架核心,爲開發者提供一個選擇自由的Web框架。基於此,開發者能夠自由的選擇數據庫或模板引擎,爲本身的Web應用作合適的選擇。python

最小應用

經過flask實現一個Hello World只須要幾行代碼linux

from flask import Flask
app = Flask(__name__)

@app.route('/')
def hello_world():
    return 'Hello, World!'

把一頭大象放進冰箱只需三步:web

  1. 引用Flask類,並建立Flask類的實例。這個實例就是HelloWorld應用的WSGI接口。
  2. 編寫hello_world函數,返回'hello, World!'字符串消息。
  3. 使用route裝飾器,爲hello_world建立路徑爲'/'的路由。

這個示例代碼與0.10版不一樣,在舊版文檔中,經過在代碼中添加app.run()方法來運行這個Web應用,而在0.12版文檔中,應用的啓動工做使用了命令行的方式來處理:數據庫

$ export FLASK_APP=hello.py
$ flask run
 * Running on http://127.0.0.1:5000/

或者:flask

$ export FLASK_APP=hello.py
$ python -m flask run
 * Running on http://127.0.0.1:5000/

經過給FLASK_APP環境變量賦值,告訴flask它的web應用是哪一個。我嘗試了在代碼中使用app.run()方法啓動,也同樣能夠執行。後端

from flask import Flask

app = Flask(__name__)

@app.route('/')
def hello_world():
    return 'Hello World!'

if __name__ == '__main__':
    app.run('0.0.0.0')

Debug模式

開啓debug模式可實現代碼變動的熱加載,即:代碼修改後,不須要重啓flask server,就能夠自動觸發變動代碼的載入。
另外,開啓debug模式能夠實如今頁面查看運行中的錯誤信息,追蹤錯誤發生緣由,適合開發過程當中的錯誤調試。
開啓Debug模式的方法包括:瀏覽器

$ export FLASK_DEBUG=1
$ flask run

以及在代碼中,爲Flask類實例的run方法中,指明debug參數爲True:安全

app.run(debug=True)

路由

在Flask下,用戶可使用@app.route()裝飾器爲頁面設計具備可讀性的靜態路由,也能夠在路由部分中加入變量,以使路由動態可變。
路由的形式相似於linux下的文件路徑。
示例以下:cookie

#靜態路由
@app.route('/hello')
def hello():
    return 'Hello, World'
#使用動態變量的路由(未指定變量類型)
@app.route('/user/<username>')
def show_user_profile(username):
    # show the user profile for that user
    return 'User %s' % username

#使用動態變量的路由(指定變量類型)
@app.route('/post/<int:post_id>')
def show_post(post_id):
    # show the post with the given id, the id is an integer
    return 'Post %d' % post_id

指定的路由變量,能夠做爲被裝飾的函數參數傳入進來。當路由尾部加入'/'時,不管在瀏覽器地址欄中輸入的網址尾部是否加'/',瀏覽器都會自動重定向到有/的路由上。

url_for()函數

flask模塊提供了url_for()函數用於獲取函數的URL,所以在項目中全部引用到URL字符串的地方,均可以使用url_for(func, **kwargs)來獲取函數的URL,這樣作的好處在於,可使項目更容易維護。當某函數URL發生變動時,只需修改一處地方便可,而無須修改每一處URL引用。我的認爲,在開發過程的任什麼時候候,使用硬編碼都是極爲不妥的。

HTTP方法

http做爲客戶端與服務端的交互協議,包含了不一樣類型的請求方法(method),Flask中,最長使用的是GET、PUT和POST方法,一條路由適用哪一種方法,能夠在route裝飾器中定義。如不明肯定義,route裝飾器中默認定義爲GET方法。
官方例子:

from flask import request

@app.route('/login', methods=['GET', 'POST'])
def login():
    if request.method == 'POST':
        do_the_login()
    else:
        show_the_login_form()

http還包括HEAD以及OPTIONS方法,在較新的Flask中,已經爲用戶內部實現,所以通常開發過程當中無需在乎。

靜態文件

Flask的靜態文件目錄默認爲項目目錄內的static目錄,通常全部靜態文件都存放在這個目錄內。

模板渲染

Flask內置了Jinja2做爲模板引擎,並提供render_template方法用於模板渲染,使用起來很方便,只需在方法內指定須要渲染的html文件名稱,並傳入模板變量值便可實現模板渲染。
官方示例:

from flask import render_template

@app.route('/hello/')
@app.route('/hello/<name>')
def hello(name=None):
    return render_template('hello.html', name=name)

默認狀況下,Flask會到當前項目目錄下的templates目錄內尋找模板文件。
官方模板文件示例:

<!doctype html>
<title>Hello from Flask</title>
{% if name %}
  <h1>Hello {{ name }}!</h1>
{% else %}
  <h1>Hello, World!</h1>
{% endif %}

模板文件之間可實現繼承,這一特性保證了不一樣頁面內的重複頁面元素(頁頭、頁腳、導航欄)等,可經過模板繼承的方式迅速實現。

訪問請求數據

來自客戶端的http請求,在server端以request對象存在。
Flask爲每個request建立一個處理線程,並在線程內部建立上下文實現線程安全。所以開發者在開發過程當中不須要爲線程安全費太多心思。
關於request對象,獲取客戶端傳輸來的數據方式很是簡單,相似於字典的形式,只須要在request.method中指明key的值便可實現:

#獲取登陸表單數據
@app.route('/login', methods=['POST', 'GET'])
def login():
    error = None
    if request.method == 'POST':
        if valid_login(request.form['username'],
                       request.form['password']):
            return log_the_user_in(request.form['username'])
        else:
            error = 'Invalid username/password'
    # the code below is executed if the request method
    # was GET or the credentials were invalid
    return render_template('login.html', error=error)

文檔在此處還說起了文件上傳場景以及cookie的簡單用法,後續文檔應當有更加詳細的記錄,在此不詳述。

錯誤與重定向

Flask使用redirect()函數處理重定向邏輯。使用abort(error_code)處理錯誤返回。
若但願對錯誤頁面進行定製,可以使用errorhandler(error_code)裝飾器修飾對應的視圖函數,定義本地錯誤頁面。

關於應答

flask有本身的應答處理邏輯,可大體總結爲:
1.視圖函數返回字符串時,flask會自動將返回字符串封裝如標準response對象內
2.用戶也能夠在視圖函數內使用make_response()函數建立response對象並返回,這樣作的意義是,在返回前用戶能夠對response對象的部份內容進行設置,例如cookie。
3.若是返回對象是一個tuple,那麼內容順序格式應知足(response, status, headers)這樣的格式

會話session

session記錄了客戶端與server之間的一些信息,官方文檔給出了用戶登錄狀態的例子。經過判斷session中是否存在username鍵值來判斷用戶是否已登陸,以此爲依據返回不一樣的展現內容。
示例以下:

from flask import Flask, session, redirect, url_for, escape, request

app = Flask(__name__)

@app.route('/')
def index():
    if 'username' in session:
        return 'Logged in as %s' % escape(session['username'])
    return 'You are not logged in'

@app.route('/login', methods=['GET', 'POST'])
def login():
    if request.method == 'POST':
        session['username'] = request.form['username']
        return redirect(url_for('index'))
    return '''
        <form method="post">
            <p><input type=text name=username>
            <p><input type=submit value=Login>
        </form>
    '''

@app.route('/logout')
def logout():
    # remove the username from the session if it's there
    session.pop('username', None)
    return redirect(url_for('index'))

# set the secret key.  keep this really secret:
app.secret_key = 'A0Zr98j/3yX R~XHH!jmN]LWX/,?RT'

使用session的前提是必須設置密鑰,密鑰的獲取可使用python提供的隨機函數生成。

>>> import os
>>> os.urandom(24)

日誌模塊

flask的日誌模塊與python的logging模塊使用方式相似,應該是作了內部集成,代碼形式略微不一樣,在此作記錄:

app.logger.debug('A value for debugging')
app.logger.warning('A warning occurred (%d apples)', 42)
app.logger.error('An error occurred')
相關文章
相關標籤/搜索