一、路由
使用 route()
裝飾器來把函式繫結到 URL:
@app.route('/') def index(): return 'Index Page' @app.route("/hello") def view_func(): return "hello world"
但是能做的不僅僅是這些!你可以動態變化 URL 的某些部分, 還可以為一個函式指定多個規則。
變數規則
通過把 URL 的一部分標記為 <variable_name>
就可以在 URL 中新增變數。標記的 部分會作為關鍵字引數傳遞給函式。通過使用 <converter:variable_name>
,可以 選擇性的加上一個轉換器,為變數指定規則。請看下面的例子:
@app.route('/user/<username>') def show_user_profile(username): # 不宣告轉換器時,預設為String型別,接受任何不包含斜槓的文字 return 'User %s' % username @app.route('/post/<int:post_id>') def show_post(post_id): # post_id只能是int型別 return 'Post %d' % post_id @app.route('/path/<path:subpath>') def show_subpath(subpath): # path類似string,但可以包含斜槓 return 'Subpath %s' % subpath
唯一的 URL / 重定向行為
以下兩條規則的不同之處在於是否使用尾部的斜槓。:
@app.route('/projects/') def projects(): return 'The project page' @app.route('/about') def about(): return 'The about page'
projects
的 URL 是中規中矩的,尾部有一個斜槓,看起來就如同一個資料夾。 訪問一個沒有斜槓結尾的 URL 時 Flask 會自動進行重定向,幫你在尾部加上一個斜槓。
about
的 URL 沒有尾部斜槓,因此其行為表現與一個檔案類似。如果訪問這個 URL 時新增了尾部斜槓就會得到一個 404 錯誤。這樣可以保持 URL 唯一,並幫助 搜尋
URL 構建
url_for()
函式用於構建指定函式的 URL。它把函式名稱作為第一個 引數。它可以接受任意個關鍵字引數,每個關鍵字引數對應 URL 中的變數。未知變數 將新增到 URL 中作為查詢引數。
為什麼不在把 URL 寫死在模板中,而要使用反轉函式 url_for()
動態構建?
-
反轉通常比硬編碼 URL 的描述性更好。
-
你可以只在一個地方改變 URL ,而不用到處亂找。
-
URL 建立會為你處理特殊字元的轉義和 Unicode 資料,比較直觀。
-
生產的路徑總是絕對路徑,可以避免相對路徑產生副作用。
-
如果你的應用是放在 URL 根路徑之外的地方(如在
/myapplication
中,不在/
中),url_for()
會為你妥善處理。
例如,這裡我們使用 test_request_context()
方法來嘗試使用 url_for()
。 test_request_context()
告訴 Flask 正在處理一個請求,而實際上也許我們正處在互動 Python shell 之中, 並沒有真正的請求。
from flask import Flask, escape, url_for app = Flask(__name__) @app.route('/') def index(): return 'index' @app.route('/login') def login(): return 'login' @app.route('/user/<username>') def profile(username): return '{}\'s profile'.format(escape(username)) with app.test_request_context(): print(url_for('index')) print(url_for('login')) print(url_for('login', next='/')) print(url_for('profile', username='John Doe')) / /login /login?next=/ /user/John%20Doe
指定請求方式
在 Flask 中,定義路由其預設的請求方式為:
- GET
- OPTIONS(自帶)
- HEAD(自帶)
利用methods引數可以指定一個介面的請求方式:
@app.route("/hello1", methods=["POST"]) def view_func_1(): return "hello world 1" @app.route("/hello2", methods=["GET", "POST"]) def view_func_2(): return "hello world 2"
二、藍圖
在一個Flask 應用專案中,如果業務檢視過多,可否將以某種方式劃分出的業務單元單獨維護,將每個單元用到的檢視、靜態檔案、模板檔案等獨立分開?例如從業務角度上,可將整個應用劃分為使用者模組單元、商品模組單元、訂單模組單元,如何分別開發這些不同單元,並最終整合到一個專案應用中?在Django中這種需求是如何實現的?
在Django中我們是將一個個功能劃分為一個個子應用去獨立開發,而在Flask中,使用藍圖Blueprint來分模組組織管理。
藍圖實際可以理解為是一個儲存一組檢視方法的容器物件,其具有如下特點:
- 一個應用可以具有多個Blueprint
- 可以將一個Blueprint註冊到任何一個未使用的URL下比如 “/user”、“/goods”
- Blueprint可以單獨具有自己的模板、靜態檔案或者其它的通用操作方法,它並不是必須要實現應用的檢視和函式的
- 在一個應用初始化時,就應該要註冊需要使用的Blueprint
但是一個Blueprint並不是一個完整的應用,它不能獨立於應用執行,而必須要註冊到某一個應用中。
使用方式
使用藍圖可以分為三個步驟
-
建立一個藍圖物件
user_bp=Blueprint('user',__name__)
-
在這個藍圖物件上進行操作,註冊路由,指定靜態資料夾,註冊模版過濾器
@user_bp.route('/') def user_profile(): return 'user_profile'
-
在應用物件上註冊這個藍圖物件
app.register_blueprint(user_bp)
對於一個打算包含多個檔案的藍圖,通常將建立藍圖物件放到Python包的__init__.py
檔案中
--------- project # 工程目錄 |------ main.py # 啟動檔案 |------ user #使用者藍圖 | |--- __init__.py # 此處建立藍圖物件 | |--- passport.py | |--- profile.py | |--- ... | |------ goods # 商品藍圖 | |--- __init__.py | |--- ... |...
擴充套件用法
1 指定藍圖的url字首
在應用中註冊藍圖時使用url_prefix
引數指定
app.register_blueprint(user_bp, url_prefix='/user')
app.register_blueprint(goods_bp, url_prefix='/goods')
2 藍圖內部靜態檔案
和應用物件不同,藍圖物件建立時不會預設註冊靜態目錄的路由。需要我們在 建立時指定 static_folder 引數。
下面的示例將藍圖所在目錄下的static_admin目錄設定為靜態目錄
admin = Blueprint("admin",__name__,static_folder='static_admin') app.register_blueprint(admin,url_prefix='/admin')
現在就可以使用/admin/static_admin/<filename>
訪問static_admin
目錄下的靜態檔案了。
也可通過static_url_path
改變訪問路徑
admin = Blueprint("admin",__name__,static_folder='static_admin',static_url_path='/lib') app.register_blueprint(admin,url_prefix='/admin')
3 藍圖內部模板目錄
藍圖物件預設的模板目錄為系統的模版目錄,可以在建立藍圖物件時使用 template_folder 關鍵字引數設定模板目錄
admin = Blueprint('admin',__name__,template_folder='my_templates')