可以翻譯成“視圖入口”,就是個(gè)名字。url_for可以用到,其他方面也可以用到(比如導(dǎo)航條確定當(dāng)前頁(yè)面),因?yàn)閑ndpoint在一個(gè) app 里唯一對(duì)應(yīng)到一個(gè) view function。
翻譯整理自Stack Overflow:http://stackoverflow.com/questions/19261833/what-is-an-endpoint-in-flask
原文中用到了my_greeting視圖函數(shù)/端點(diǎn),我估計(jì)是答者筆誤,故修改為了give_greeting。
Flask路由是如何工作的
整個(gè)flask框架(及以Werkzeug類庫(kù)為基礎(chǔ)構(gòu)建的應(yīng)用)的程序理念是把URL地址映射到你想要運(yùn)行的業(yè)務(wù)邏輯上(最典型的就是視圖函數(shù)),例如:
@app.route('/greeting/')defgive_greeting(name):return'Hello, {0}!'.format(name)
注意,add_url_rule函數(shù)實(shí)現(xiàn)了同樣的目的,只不過(guò)沒(méi)有使用裝飾器,因此,下面的程序是等價(jià)的:
# 抬頭沒(méi)有使用路由裝飾器,我們?cè)谧詈笥昧硪环N方法添加路由.defgive_greeting(name):return'Hello, {0}!'.format(name)app.add_url_rule('/greeting/','give_greeting', give_greeting)
備注:add_url_rule()中3個(gè)參數(shù)依次是rule、view_func、endpoint.
假設(shè)www.example.org站點(diǎn)定義了以上視圖,用戶在瀏覽器中輸入以下地址
http://www.example.org/greeting/Mark
Flask的工作就是捕捉這個(gè)URL地址,弄清用戶想要做什么,并在眾多的Python函數(shù)中匹配一個(gè)可以處理它的函數(shù),回到我們的實(shí)例中,URL地址就是
/greeting/Mark
拿著這個(gè)地址到路由表中做匹配,flask發(fā)現(xiàn)這個(gè)地址指向了give_greeting函數(shù)。
然而,當(dāng)我們用這種最常用的方法創(chuàng)建視圖時(shí),flask卻向我們隱藏了一些其他的細(xì)節(jié)信息。在這個(gè)場(chǎng)景中,flask并沒(méi)有直接從URL地址跳轉(zhuǎn)到應(yīng)該響應(yīng)它請(qǐng)求的視圖函數(shù)上:
URL (http://www.example.org/greeting/Mark) 被視圖函數(shù)處理 ("give_greeting"函數(shù))
事實(shí)上,這里還有另一個(gè)步驟--把URL地址映射到端點(diǎn)上(URL-->endpoint-->viewfunction):
URL (http://www.example.org/greeting/Mark) 映射到端點(diǎn)"give_greeting"上.指向端點(diǎn)"give_greeting"的請(qǐng)求被視圖函數(shù)"give_greeting"處理.
從根本上來(lái)說(shuō),端點(diǎn)就是程序中一組邏輯處理單元的ID,該ID對(duì)應(yīng)的代碼決定了對(duì)此ID請(qǐng)求應(yīng)該作出何種響應(yīng)。通常,端點(diǎn)與視圖函數(shù)同名,但是你也可以修改它,例如:
@app.route('/greeting/', endpoint='say_hello')defgive_greeting(name):return'Hello, {0}!'.format(name)
現(xiàn)在就成了這樣:
URL (http://www.example.org/greeting/Mark) 映射到端點(diǎn)"say_hello"上.指向端點(diǎn)"say_hello"的請(qǐng)求被視圖函數(shù)"give_greeting"處理.
Endpoint有什么作用
端點(diǎn)通常用作反向查詢URL地址(viewfunction-->endpoint-->URL)。例如,在flask中有個(gè)視圖,你想把它關(guān)聯(lián)到另一個(gè)視圖上(或從站點(diǎn)的一處連接到另一處)。不用去千辛萬(wàn)苦的寫它對(duì)應(yīng)的URL地址,直接使用URL_for()就可以啦:
@app.route('/')def index():? ? print url_for('give_greeting', name='Mark') # 打印出'/greeting/Mark'@app.route('/greeting/')def give_greeting(name):? ? return'Hello, {0}!'.format(name)
備注:url_for()中g(shù)ive_greeting是端點(diǎn)名.
這樣做是大有裨益的:我們可以隨意改變應(yīng)用中的URL地址,卻不用修改與之關(guān)聯(lián)的資源的代碼。
為何要多此一舉
那么問(wèn)題來(lái)了:為何要多此一舉,為何要先把URL映射到端點(diǎn)上,再通過(guò)端點(diǎn)映射到視圖函數(shù)上,為何不跳過(guò)中間的這個(gè)步驟?
原因就是采用這種方法能夠使程序更高、更快、更強(qiáng)。例如藍(lán)本。藍(lán)本允許我們把應(yīng)用分割為一個(gè)個(gè)小的部分,現(xiàn)在admin藍(lán)本中含有超級(jí)管理員級(jí)的資源,user藍(lán)本中則含有用戶一級(jí)的資源。
藍(lán)本允許咱們把應(yīng)用分割為一個(gè)個(gè)以命名空間區(qū)分的小部分:
main.py:
fromflaskimportFlask, Blueprintfromadminimportadminfromuserimportuserapp = Flask(__name__)app.register_blueprint(admin, url_prefix='admin')app.register_blueprint(user, url_prefix='user')
admin.py:
admin = Blueprint('admin', __name__)@admin.route('/greeting')defgreeting():return'Hello, administrative user!'
user.py:
user = Blueprint('user', __name__)@user.route('/greeting')defgreeting():return'Hello, lowly normal user!'
注意,在兩個(gè)藍(lán)本中路由地址'/greeting'的函數(shù)都叫"greeting"。如果我想調(diào)用admin對(duì)應(yīng)的greeting函數(shù),我不能說(shuō)“我想要greeting”,因?yàn)檫@里還有一個(gè)user對(duì)應(yīng)的greeting函數(shù)。端點(diǎn)這時(shí)就發(fā)揮作用了:指定一個(gè)藍(lán)本名稱作為端點(diǎn)的一部分--通過(guò)這種方式端點(diǎn)實(shí)現(xiàn)了對(duì)命名空間的支持。所以,我們可以這樣寫:
printurl_for('admin.greeting') # Prints'/admin/greeting'printurl_for('user.greeting') # Prints'/user/greeting'
來(lái)發(fā)實(shí)例
fromflaskimportFlask, url_forapp = Flask(__name__)# We can use url_for('foo_view') for reverse-lookups in templates or view functions@app.route('/foo')deffoo_view():pass# We now specify the custom endpoint named 'bufar'. url_for('bar_view') will fail!@app.route('/bar', endpoint='bufar')defbar_view():passwithapp.test_request_context('/'):print(url_for('foo_view'))#/fooprint(url_for('bufar'))#/bar# url_for('bar_view') will raise werkzeug.routing.BuildErrorprint(url_for('bar_view'))#端點(diǎn)bar_view是沒(méi)有定義的
程序運(yùn)行結(jié)果
python_endpoint_程序運(yùn)行結(jié)果
更多參考: