《Flask Web Development》第2章 基礎(chǔ)應(yīng)用的結(jié)構(gòu)

本章將開始熟悉一個最基本的Flask應(yīng)用的不同部分,并自己動手構(gòu)建一個Flask Web應(yīng)用。

初始化

所有Flask的應(yīng)用程序必須構(gòu)建一個Flask的對象,然后通過協(xié)議將從客戶端收到的所有請求交給這個實(shí)例進(jìn)行處理:

from flask import Flask
Flask app = Flask(__name__)

關(guān)于Flask中參數(shù)的說明:Flask的構(gòu)造函數(shù)只接收一個參數(shù),這里是__name__會指向該程序片段所在的模塊。目前只需要知道使用__name__就夠了。

路由和函數(shù)

Web客戶端請求的鏈接地址不同,后臺會通過route來決定每個鏈接對應(yīng)的哪塊處理代碼。最簡單的做法就是使用Flask實(shí)例中提供的方法app.route來注冊一個方法到路由上:

@app.route('/') 
def index():
    return '<h1>Hello World!<\/h1\>'

Flask路由上是可以配置動態(tài)參數(shù)的:

@app.route('/user/<name>') 
def user(name):
    return '<h1>Hello, %s!</h1>' % name

在上例中,尖括號中間的內(nèi)容是動態(tài)的,任何匹配了該形式的URL會映射到這個路由上,然后調(diào)用對應(yīng)的View Function。默認(rèn)的,傳遞的參數(shù)被當(dāng)做string處理,當(dāng)然你也可以執(zhí)行它們 比如@app.route /user/<int:id>

Server啟動

應(yīng)用程序?qū)嵗幸粋€run方法用于啟動Flask所集成的Web服務(wù)器:

if __name__ == '__main__': 
    app.run(debug=True)

if判定條件是為了保證:只有該script被直接執(zhí)行的時候才去啟動server,因?yàn)槿绻搒cript是被當(dāng)做模塊引入的,那么很可能在其他的script中已經(jīng)啟動過server了。

啟動過后server會一直輪巡檢查是否收到有客戶端的請求,Mac OS下可以通過ctrl+c 停止server。run方法有很多可選參數(shù)可以配置,比如設(shè)置debug=True能夠進(jìn)入調(diào)試模式方便查看調(diào)試信息。

一個完整的應(yīng)用

在前面的代碼片段已經(jīng)說明了該例子的各個部分,可以嘗試在自己的編輯器上構(gòu)建這么一個hello.py:

from flask import Flask

app = Flask(__name__)

@app.route('/')
def index():
    return '<h1>Hello World!</h1>'

if __name__ == '__main__':
    app.run(debug=True)

確保保證你是在虛擬環(huán)境下運(yùn)行hello.py,最后訪問 http://127.0.0.1:5000/ 即可看到Hello World頁面。

請求的生命周期

應(yīng)用與請求上下文

每個來自客戶端的請求處理過程都需要構(gòu)建一些對象,比如request對象。

為了將處理請求需要的參數(shù)傳遞給View Function,我們可以給View Function的鏈接中增加動態(tài)參數(shù),但是那樣參數(shù)一多久會顯得混亂了。Flask采用了Context中保存對象的做法,request對象會從context中獲取屬于當(dāng)前請求的參數(shù),以方便全局訪問一些對象,如下就是一個例子:

from flask import request 

@app.route('/')
def index():
    user_agent = request.headers.get('User-Agent') 
    return '<p>Your browser is %s</p>' % user_agent

當(dāng)然不同的請求訪問到的是不同的request對象,因?yàn)镕lask中采用了一定的機(jī)制保證獲取對象的正確獲取,邏輯不復(fù)雜有興趣可以細(xì)看相應(yīng)章節(jié)。

在Flask中使用了一個map結(jié)構(gòu)來保存Route和View Function的對應(yīng)關(guān)系,如下示例代碼可以查看該map的存儲鍵值對:

(venv) $ python
>>> from hello import app
>>> app.url_map
Map([<Rule '/' (HEAD, OPTIONS, GET) -> index>,
     <Rule '/static/<filename>' (HEAD, OPTIONS, GET) -> static>,
     <Rule '/user/<name>' (HEAD, OPTIONS, GET) -> user>])
鉤子函數(shù)

于面向切面編程概念中,我們通常希望請求前、后可能希望做一些通用的處理,在Flask中可以使用一些鉤子函數(shù)來達(dá)到這個目的,F(xiàn)lask提供了四個鉤子函數(shù):

  • before_first_request
  • before_request
  • after_request
  • teardown_request

鉤子函數(shù)的一個典型的應(yīng)用場景是:在第一次請求中通過before_first_request來獲取到用戶數(shù)據(jù)存儲到Context中,以后請求就可以直接從Context中直接取用戶數(shù)據(jù)了。

響應(yīng)結(jié)果

返回給前臺的數(shù)據(jù)可以是一個字符串,還可以攜帶第二個甚至第三個參數(shù):

@app.route('/') 
def index():
    return '<h1>Bad Request</h1>', 400

更好的做法是返回一個response對象:

from flask import make_response

@app.route('/') def index():
    response = make_response('<h1>This document carries a cookie!</h1>') 
    response.set_cookie('answer', '42')
    return response

還有其他一種方式是直接定位到另一個地址:

from flask import redirect

@app.route('/') 
def index():
    return redirect('http://www.example.com')

有一中特殊的用法,就是abort,用來再頁面處理錯誤直接返回404:

from flask import abort

@app.route('/user/<id>') 
def get_user(id):
    user = load_user(id) if not user:
        abort(404)
    return '<h1>Hello, %s</h1>' % user.name

Flask的擴(kuò)展

帶命令行選項(xiàng)的Flask-Script

Flask有大量的用于不同目的的擴(kuò)展可以使用,如果這些還不滿足要求你還可以開發(fā)自己的擴(kuò)展。該部分會介紹如何集成一個用于加強(qiáng)命令行的功能的擴(kuò)展,使命令行能攜帶參數(shù)。

  • 第一步,使用pip安裝該擴(kuò)展:
(venv) $ pip install flask-script
  • 第二步,基于hello.py修改代碼:
from flask import Flask
rom flask.ext.script import Manager
    
app = Flask(__name__)
manager = Manager(app)

@app.route('/')
def index():
return '<h1>Hello World!</h1>'

if __name__ == '__main__':
        manager.run()
  • 第三步,命令行執(zhí)行:
(venv) $ python hello.py
usage: hello.py [-?] {shell,runserver} ...

positional arguments:
  {shell,runserver}
    shell            Runs a Python shell inside Flask application context.
    runserver        Runs the Flask development server i.e. app.run()

optional arguments:
      -?, --help         show this help message and exit

如上,必選參數(shù)為runserver/shell, 這里我們要做的是run server。要查看runserver有哪些參數(shù),可以如下方式查看:

(venv) $ python hello.py runserver --help
usage: hello.py runserver [-h] [-t HOST] [-p PORT] [--threaded]
                          [--processes PROCESSES] [--passthrough-errors] [-d]
                          [-r]
Runs the Flask development server i.e. app.run()

optional arguments:
    -h, --help
    -t HOST, --host HOST
    -p PORT, --port PORT
    --threaded
    --processes PROCESSES
    --passthrough-errors
    -d, --no-debug
    -r, --no-reload

現(xiàn)在能夠基于命令行直接設(shè)置server的host和port等參數(shù)了,可以將主機(jī)地址設(shè)置為0.0.0.0看看:

(venv) $ python hello.py runserver --host 0.0.0.0
* Running on http://0.0.0.0:5000/
* Restarting with reloader
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

推薦閱讀更多精彩內(nèi)容