何為路由被丧?
顧名思義就是一條路徑鸿染,這條路引領(lǐng) url 從瀏覽器到WSGI服務(wù)器酸休,然后將處理結(jié)果返回到Browser。在 Flask 框架中 洋访,路由的作用就是為用戶請(qǐng)求的URL找出其對(duì)應(yīng)的處理函數(shù) 镣陕。
1. 注冊(cè)路由
Flask 框架中: 根據(jù)HTTP請(qǐng)求的URL在路由表中尋找對(duì)應(yīng)的URL規(guī)則,找到對(duì)應(yīng)的視圖函數(shù)姻政,并將視圖函數(shù)的執(zhí)行結(jié)果返回給WSGI服務(wù)器呆抑。注:Flask封裝了一個(gè)簡(jiǎn)單的開(kāi)發(fā)用的WSGI服務(wù)器,調(diào)用run函數(shù)時(shí)汁展,該服務(wù)器啟動(dòng)鹊碍。
其實(shí),在Flask里邊有一個(gè)中轉(zhuǎn)的機(jī)制---------endpoint
在Flask內(nèi)部使用兩張表維護(hù)路由:
url_map:維護(hù)URL規(guī)則和endpoint的映射
view_functions:維護(hù)endpoint和視圖函數(shù)的映射食绿。
默認(rèn)訪問(wèn)點(diǎn) :當(dāng)我們使用route裝飾器注冊(cè)路由時(shí)妹萨,默認(rèn)使用被裝飾函數(shù)的 函數(shù)名(name)作為訪問(wèn)點(diǎn)。
自定義訪問(wèn)點(diǎn) :可以在使用route裝飾器或調(diào)用add_url_rule()方法注冊(cè)路由時(shí)炫欺,使用 endpoint關(guān)鍵字參數(shù)改變這一默認(rèn)行為乎完。
@app.route('/test',endpoint='self_define')
def test():pass
2. 兩種路由方式
① 調(diào)用 add_url_route() 為函數(shù)指定一個(gè)路由
def test():
return 'this is test'
app.add_url_route('/test',view_func=test)
② 用 route 裝飾器將一個(gè)url規(guī)則綁定到一個(gè)視圖函數(shù)上
@app.route('/test')
def test():
return 'this is test'
顯然, 使用裝飾器讓代碼看起來(lái)更加的簡(jiǎn)潔明了
3. 動(dòng)態(tài)路由
要給 URL 添加變量部分品洛,你可以把這些特殊的字段標(biāo)記為 <variable_name> 树姨, 這個(gè)部分將會(huì)作為命名參數(shù)傳遞到你的函數(shù)摩桶。規(guī)則可以用 <converter:variable_name> 指定一個(gè)可選的轉(zhuǎn)換器
@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
轉(zhuǎn)換器有下面幾種:
int 接受整數(shù)
float 接受浮點(diǎn)數(shù)
path 和默認(rèn)的相似,但接受斜線
這里解釋一下
假如我們要訪問(wèn)四個(gè)文件帽揪,目錄結(jié)構(gòu)如上圖所示
@app.route('/file/<fname>')
def v_file(fname):
fullname = os.path.join('/A/B',fname)
f = open(fullname)
content = f.read()
f.close()
return cnt
測(cè)試結(jié)果表明硝清,/file/a.txt和/file/b.txt都沒(méi)有問(wèn)題,但是/file/C/c.txt和 /file/C/d.txt卻會(huì)失敗转晰。
這是因?yàn)槁茫J(rèn)情況下,在URL規(guī)則中的變量被視為不包含/的字符串查邢。/file/C/c.txt 是沒(méi)有辦法匹配URL規(guī)則/file/的蔗崎。
如果這里改為path,則四個(gè)文件都可以訪問(wèn)到
@app.route('/file/<path:fname>')
def v_file(fname):
fullname = os.path.join('/A/B',fname)
f = open(fullname)
content = f.read()
f.close()
return cnt
4. 添加HTTP方法
HTTP有許多不同的訪問(wèn) URL 方法扰藕。默認(rèn)情況下缓苛,路由只回應(yīng) GET 請(qǐng)求,但是通過(guò) route() 裝飾器傳遞 methods 參數(shù)可以改變這個(gè)行為邓深。例如:
@app.route('/login', methods=['GET', 'POST'])
def login():
if request.method == 'POST':
do_the_login()
else:
show_the_login_form()
5. 靜態(tài)目錄路由
當(dāng)創(chuàng)建應(yīng)用實(shí)例時(shí)未桥,F(xiàn)lask將自動(dòng)添加一條靜態(tài)目錄路由,其訪問(wèn)點(diǎn) 始終被設(shè)置為static芥备,URL規(guī)則默認(rèn)被設(shè)置為/static冬耿,本地路徑默認(rèn)被 設(shè)置為應(yīng)用文件夾下的static子文件夾
改變默認(rèn)的本地路徑 :可以在創(chuàng)建應(yīng)用對(duì)象時(shí)使用關(guān)鍵字參數(shù)static_folder改變 默認(rèn)的靜態(tài)文件夾。例如萌壳,你的靜態(tài)文件都存放在應(yīng)用下的assets目錄下亦镶, 那么可以按如下的方式創(chuàng)建應(yīng)用對(duì)象:
app = Flask(name,static_folder='assets')
6. url_for函數(shù)
url_for() 函數(shù)最簡(jiǎn)單的用法是以視圖函數(shù)名(或者app.add_url_route() 定義路由時(shí)使用的端點(diǎn)名)作為參數(shù),返回對(duì)應(yīng)的URL讶凉。例如染乌,在當(dāng)前程序中調(diào)用url_for('index') 得到的結(jié)果是/。調(diào)用url_for('index', _external=True) 返回的則是絕對(duì)地址懂讯,在這個(gè)示例中是http://localhost:5000/
參數(shù)分別是 視圖函數(shù) 荷憋、變量、參數(shù)
print url_for('A',name='B',format='c')
輸出
A/B?format=c
下面這個(gè)使用_anchor關(guān)鍵字可以為生成的URL添加錨點(diǎn)
print url_for('A',_anchor='d')
輸出
/A#d
使用 render_template() 方法來(lái)渲染模板褐望。Flask 會(huì)在 templates 文件夾里尋找模板勒庄。
@main.route('/', methods=['GET', 'POST'])
def index():
return render_template('main/index.html')
這里不再細(xì)講,url_for函數(shù)有其他功能瘫里,
1. 傳入url_for() 的關(guān)鍵字參數(shù)不僅限于動(dòng)態(tài)路由中的參數(shù)实蔽。函數(shù)能將任何額外參數(shù)添加到查詢字符串中。例如谨读,url_for('index', page=2) 的返回結(jié)果是/?page=2局装。
2 通過(guò) 路由.視圖函數(shù) 可以定位到其他界面,例如
<a href="{{ url_for('main.index') }}">首頁(yè)</a>