Werkzeug庫——routing模組

發表於2017-05-26

Werkzeug庫的routing模組的主要功能在於URL解析。對於WSGI應用來講,不同的URL對應不同的檢視函式,routing模組則會對請求資訊的URL進行解析並匹配,觸發URL對應的檢視函式,以此生成一個響應資訊。routing模組的解析和匹配功能主要體現在三個類上:RuleMapMapAdapter

Rule

Rule類繼承自RuleFactory類。一個Rule的例項代表一個URL模式,一個WSGI應用可以處理很多不同的URL模式,這也就是說可以產生很多不同的Rule例項。這些Rule例項最終會作為引數傳遞給Map類,形成一個包含所有URL模式的物件,通過這個物件可以解析並匹配請求對應的檢視函式。

關於Rule類有一些常用的方法:

  • empty() ——在實際情況中,Rule例項會和一個Map例項進行繫結。通過empty()方法可以將Rule例項和Map例項解除繫結。
  • get_empty_kwargs() ——在empty()方法中呼叫,可以獲得之前Rule例項的引數,以便重新構造一個Rule例項。
  • get_rules(map) ——這個方法是對RuleFactory類中get_rules方法的重寫,返回Rule例項本身。
  • refresh() ——當修改Rule例項(URL規則)後可以呼叫該方法,以便更新Rule例項和Map例項的繫結關係。
  • bind(map, rebind=False) ——將Rule例項和一個Map例項進行繫結,這個方法會呼叫complie()方法,會給Rule例項生成一個正規表示式。
  • complie() ——根據Rule例項的URL模式,生成一個正規表示式,以便後續對請求的path進行匹配。
  • match(path) ——將Rule例項和給定的path進行匹配。在呼叫complie()方法生成的正規表示式將會對path進行匹配。如果匹配,將返回這個path中的引數,以便後續過程使用。如果不匹配,將會由其他的Rule例項和這個path進行匹配。

注意: 在對給定的URL進行匹配的過程中,會使用一些Converters。關於Converters的資訊後續加以介紹。

Map

通過Map類構造的例項可以儲存所有的URL規則,這些規則是Rule類的例項。Map例項可以 通過後續的呼叫和給定的URL進行匹配。

關於Map類有一些常用的方法:

  • add(rulefactory) ——這個方法在構造Map例項的時候就會呼叫,它會將所有傳入Map類中的Rule例項和該Map例項建立繫結關係。該方法還會呼叫Rule例項的bind方法。
  • bind方法 ——這個方法會生成一個MapAdapter例項,傳入MapAdapter的包括一些請求資訊,這樣可以呼叫MapAdapter例項的方法匹配給定URL。
  • bind_to_environ方法 ——通過解析請求中的environ資訊,然後呼叫上面的bind方法,最終會生成一個MapAdapter例項。

MapAdapter

MapAdapter類執行URL匹配的具體工作。關於MapAdapter類有一些常用的方法:

  • dispatch方法 ——該方法首先會呼叫MapAdapter例項的match()方法,如果有匹配的Rule,則會執行該Rule對應的檢視函式。
  • match方法 ——該方法將會進行具體的URL匹配工作。它會將請求中的url和MapAdapter例項中的所有Rule進行匹配,如果有匹配成功的,則返回該Rule對應的endpoint和一些引數rvendpoint一般會對應一個檢視函式,返回的rv可以作為引數傳入檢視函式中。

一個簡單的例子

為了說明routing模組的工作原理,這裡使用Werkzeug文件中的一個例子,稍加改動後如下所示:

 

這裡我們使用werkzeug自帶的伺服器模組構造了一個Web伺服器,並且設計了一個簡單的WSGI應用——application。這個Web伺服器可以根據URL的不同返回不同的結果。關於伺服器的構造這裡不再贅述,以下部分簡單對URL Routing過程進行分析:

1. 設計URL模式

設計URL模式的過程就是構造Rule例項的過程。上面的例子中我們構造了8個Rule例項,分別對應8個不同的URL模式。每個Rule例項還對應一個endpoint,這個endpoint可以和檢視函式進行對應,以便訪問某個URL時,可以觸發與之對應的檢視函式。下面的例子展示了endpoint和檢視函式的對應關係。

2. 構造Map例項

構造Map例項時,會呼叫它的add(rulefactory)方法。這個方法會在Map例項和各個Rule例項之間建立繫結關係,並通過呼叫Rule例項的bind()方法為每個Rule例項生成一個正規表示式。

例如,對於'/about'這個URL,它對應的正規表示式為:

對於'/<int:year>/<int:month>/<int:day>/'這個URL,它對應的正規表示式為:

3. 構造MapAdapter例項

在設計WSGI應用時,上述例子通過url_map.bind_to_environ(environ)構建了一個MapAdapter例項。這個例項將請求的相關資訊和已經建立好的Map例項放在一起,以便進行URL匹配。

進行URL匹配的過程是通過呼叫MapAdapter例項的match()方法進行的。實質上,這個方法會將請求中的path傳入到所有Rule例項的match(path)方法中,經過正規表示式的匹配來分析path是否和某個Rule例項匹配。如果匹配則返回對應的endpoint和其他的引數,這可以作為引數傳入檢視函式。

4. 訪問URL可得相關結果

之後,訪問URL可以得到相對應的結果。

例如,訪問http://localhost:4000/2017/,可以得到:

Rule points to 'blog/archive' with arguments {'year': 2017}

訪問http://localhost:4000/2017/3/20/,可以得到:

Rule points to 'blog/archive' with arguments {'month': 3, 'day': 20, 'year': 2017}

訪問http://localhost:4000/about,可以得到:

Rule points to 'blog/about_me' with arguments {}

相關文章