2019年5月19日 星期日

[Python] 使用Flask建立網站(一) — 凡事都先從Hello World開始

  這次我們要來學如何使用Flask這個Python framework來建立網站。
  應該會是一系列的文章,首先介紹URL Routing的部分。

  在這之前先來看一張圖:

(來源:edureka!: https://www.youtube.com/watch?v=4XAQF9Qgtes)
  這張圖列出的是一個web framework應該會提供的幾個重要元件:
  1. URL Routing
  2. Input Form Handling and Validation
  3. Output Format with Templating Engine
  4. Database Manipulation
  5. Web Security
  6. Session Storage and Retrieval
  那要學習使用某web framework,就從這幾個元件一一去熟悉認識就對了。


  首先我們來看Flask如何做URL Routing。   例子:我們要建立一個網站,其根目錄連到的頁面會呈現Hello World這幾個字,簡單的說就是網頁版的 print("Hello World")。

  第一步當然是先下載flask:pip install flask

  再來,直接看程式碼吧!
app.py:
from flask import Flask

app = Flask(__name__)

@app.route('/')
def hello():
    return "<h3>Hello World</h3>"

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

  * 首先我們引入Flask class,Flask實例會是我們的WSGI application (WSGI就想成是程式碼與伺服器程式間的橋梁,不過這裡我們沒用到Apache或是Nginx之類的伺服器程式,WSGI其實也可作為伺服器執行)。

  * 創建Flask實例,它需要輸入application module name作為參數,輸入__name__就好,__name__指的是當前這個檔案在運行時的module名。

  * 那關鍵的URL對映handler做法呢?flask提供了route裝飾器,只要在function前綴@app.route("url"),就能表明該URL對映到此函式,作法相當簡單,另外route()內有許多option可以進行設定,像是methods可以決定這是接收哪種HTTP method (GET、POST...),預設是GET。
     在flask中,因為是使用裝飾器的方式,route邏輯是跟handler綁在一起的,這樣做的缺點是不像Django能有一塊程式碼能一目了然看到各種URL對映的handler。([Python] Django的一個小入門範例)

  執行:     輸入命令 python app.py
    預設應該會執行在 http://127.0.0.1:5000,打開瀏覽器輸入這個網址就可以看到Hello World了
    想停止就按 ctrl + c


  接下來再進階一點。

  我們嘗試將app與route分開吧。
  這樣的目錄規劃其實很常見,試想若我們的網站很大,全部URL對映的程式碼都塞在一個app.py還得了。

  目錄變成

/test
    |--- run.py
    |--- /web
             |--- app.py
             |--- routes.py

  run.py用來執行app.py裡的flask app。
  app.py裡建立flask app,而routes.py則有URL映射。 run.py:
from web.app import app

if __name__ == '__main__':
    app.run(debug=True)
app.py:
from flask import Flask

app = Flask(__name__)
from . import routes   ## 一定要在app後,因為routes.py會import app.py裡的app
routes.py:
from .app import app

@app.route('/')
def hello():
    return "<h3>Hello World</h3>"

  執行 python run.py

  但circular import看了實在感覺有點怪 (app.py先是引入routes,routes又需要引入app),我們可以透過flask提供的Blueprint解決這個困擾。

app.py:
from flask import Flask
from .routes import home

app = Flask(__name__)
app.register_blueprint(home)   ## 將blueprint註冊到app下
routes.py:
from flask import Blueprint

home = Blueprint('home', __name__)

@home.route('/')    ## 注意這裡變成home.route
def hello():
    return "<h3>Hello World</h3>"

  這樣看起來好多了。

  Blueprint的功用當然不僅為了解決circular import,它也幫助我們的route模組化,這在大型專案的維護很有幫助。
  像下面我們統一了admin為處理關於admin權限的url對映。

app.py:
from flask import Flask
from .routes import admin

app = Flask(__name__)
app.register_blueprint(admin, url_prefix='/admin')
routes.py:
from flask import Blueprint

admin = Blueprint('admin', __name__)

@admin.route('/login')
def login():
    return "<h3>Login</h3>"

@admin.route('/page')
def admin_page():
    return "<h3>My page</h3>"

  連上http://127.0.0.1:5000/admin/login 可以看到顯示login頁面


  參考資料:
    1. FLASK 簡介- Blueprints « Python Life

沒有留言:

張貼留言