Read Sean

          Read me, read Sean.
          posts - 508, comments - 655, trackbacks - 9, articles - 4

          [Pylons] Routes和controller,一個(gè)簡單的例子

          Posted on 2009-01-26 16:21 laogao 閱讀(3995) 評論(0)  編輯  收藏 所屬分類: On Python

          在開始之前,說點(diǎn)提外話,隨著對Pylons了解的深入,你可能時(shí)不時(shí)需要看看相關(guān)組件/軟件包是否有更新出來,方法也不復(fù)雜,通過"easy_install -U [組件名]"即可,在學(xué)習(xí)或者是開發(fā)過程中,最好是保持環(huán)境相對較新,直到出現(xiàn)相對大的release或者即將進(jìn)入產(chǎn)品部署階段。

          繼續(xù)介紹Pylons組件,先看個(gè)例子。首先用"paster controller hello"增加一個(gè)controller,路徑中會(huì)增加出以下兩個(gè)文件:
          controllers/hello.py
          tests/functional/test_hello.py

          分別對應(yīng)新增的controller類HelloController和功能測試類TestHelloController,它們分別繼承自WSGIController->BaseController和TestCase->TestController。

          我們主要看hello.py,默認(rèn)內(nèi)容如下:
          ?1?import?logging
          ?2?
          ?3?from?pylons?import?request,?response,?session,?tmpl_context?as?c
          ?4?from?pylons.controllers.util?import?abort,?redirect_to
          ?5?
          ?6?from?newapp.lib.base?import?BaseController,?render
          ?7?#from?newapp?import?model
          ?8?
          ?9?log?=?logging.getLogger(__name__)
          10?
          11?class?HelloController(BaseController):
          12?
          13?????def?index(self):
          14?????????#?Return?a?rendered?template
          15?????????#???return?render('/template.mako')
          16?????????#?or,?Return?a?response
          17?????????return?'Hello?World'

          如果你的服務(wù)器沒有Ctrl-C停掉,那么這個(gè)時(shí)候你已經(jīng)可以通過
          http://127.0.0.1:5000/hello/index
          看到該controller的處理結(jié)果了(Hello World)。

          簡單改造一下17行:
          ????????from?pylons?import?config
          ????????
          return?'<br/>'.join(config.keys())

          我們就可以在返回頁面上顯示出所有可以通過pylons.config訪問到的參數(shù)列表。出了返回文本,也可以通過render()方法交給頁面模板引擎生成頁面,也可以通過redirect_to()跳轉(zhuǎn)到其他URL。

          Pylons是如何找到該請求應(yīng)該由HelloController的index方法來處理的呢?這背后發(fā)生了什么?答案就是Routes。

          Routes的作者是Ben Bangert,是Pylons框架三個(gè)主要作者/維護(hù)者之一,早期的版本主要是仿照Ruby on Rails的routes.rb開發(fā)的,有RoR經(jīng)驗(yàn)的朋友可能一眼就能發(fā)現(xiàn)它們之間的相似之處。目前Routes的最新版是1.10.2。

          Pylons應(yīng)用中,routing的配置在config/routing.py,默認(rèn)生成的內(nèi)容如下:
          ?1?"""Routes?configuration
          ?2?
          ?3?The?more?specific?and?detailed?routes?should?be?defined?first?so?they
          ?4?may?take?precedent?over?the?more?generic?routes.?For?more?information
          ?5?refer?to?the?routes?manual?at?http://routes.groovie.org/docs/
          ?6?"""
          ?7?from?pylons?import?config
          ?8?from?routes?import?Mapper
          ?9?
          10?def?make_map():
          11?????"""Create,?configure?and?return?the?routes?Mapper"""
          12?????map?=?Mapper(directory=config['pylons.paths']['controllers'],
          13??????????????????always_scan=config['debug'])
          14?????map.minimization?=?False
          15?????
          16?????#?The?ErrorController?route?(handles?404/500?error?pages);?it?should
          17?????#?likely?stay?at?the?top,?ensuring?it?can?always?be?resolved
          18?????map.connect('/error/{action}',?controller='error')
          19?????map.connect('/error/{action}/{id}',?controller='error')
          20?
          21?????#?CUSTOM?ROUTES?HERE
          22?
          23?????map.connect('/{controller}/{action}')
          24?????map.connect('/{controller}/{action}/{id}')
          25?
          26?????return?map

          在這個(gè)配置中,對我們剛才的實(shí)例起到?jīng)Q定性作用的是第23行,我們的輸入U(xiǎn)RL為"http://127.0.0.1:5000/hello/index",其中"/hello/index"通過"/{controller}/{action}"這個(gè)表達(dá)式match出controller為hello而action為index的解析結(jié)果,從而在controllers目錄找到hello.py,和其中HelloController的index方法,進(jìn)行調(diào)用。

          map.connect()在上面代碼中體現(xiàn)出兩種用法:
          map.connect('pattern', key=value) - 指定默認(rèn)的controller、action、id等
          map.connect('pattern') - 直接指定pattern

          pattern字符串允許通配符,通常在最后一個(gè)元素上,比如'/{controller}/{action}/{*url}',將后面的整個(gè)URL片段交給前面指定的controller/action處理。除此以外,map.connect()還支持

          1- "路徑別名",如:
          map.connect('name', 'pattern', [_static=True])
          如果_static設(shè)為"True",表示為"靜態(tài)命名路徑"。
          2- 額外的匹配條件,如:
          map.connect('/{controller}/{action}/{id}', requirements={'year': '\d+',})
          map.connect('/{controller}/{action}/{id}', conditions=dict(method=['GET','POST']))

          所有的route優(yōu)先級(jí)為從上到下。Routes除了提供解析進(jìn)來的URL的邏輯,在我們的controller和template代碼中,我們還可以方便的通過WebHelpers的url_for()方法計(jì)算相應(yīng)的URL。

          Routes 1.x中的有一些仿routes.rb功能將會(huì)在2.0中被去掉,包括Route Minimization、Route Memory、Implicit Defaults等。如果有興趣的話,可以參考一下官方文檔,這里就不一一介紹了。為什么要去掉?當(dāng)然主要的動(dòng)機(jī)還是減少歧義,避免一些不必要的混淆。至于深層次的原因么,可以參考Tim Peters《The Zen of Python》中的一句經(jīng)典的Python哲學(xué):Explicit is better than implicit。什么?沒有聽說過?打開python命令行,輸入"import this"后回車,慢慢體會(huì)其中的道理吧。:)


          主站蜘蛛池模板: 东海县| 黄山市| 姜堰市| 巴南区| 资中县| 沙洋县| 龙南县| 大港区| 龙川县| 和硕县| 大余县| 新蔡县| 温宿县| 澄城县| 秦安县| 沙湾县| 平利县| 荥经县| 佛山市| 济源市| 安阳县| 榆社县| 教育| 安塞县| 滕州市| 南京市| 佛坪县| 灵山县| 财经| 绥宁县| 石家庄市| 古浪县| 宁安市| 安仁县| 彭阳县| 古田县| 都江堰市| 甘德县| 涿鹿县| 仙游县| 新田县|