剛看到一個 Python FAQ 系統. 當然這並不是最好的 FAQ 系統,不過裡面除了一般的分類索引之外,還有個非常有趣的功能是 "Show me a random article! (隨機文章)", 這功能有點像一些 IDE 剛開啟的時候出現隨機的 FAQ 視窗,每次開啟時都有不同的訊息.
TurboEntity 版 SimpleBlog 之二
用 TurboEntity 照著 'SimpleBlog Part II' 中的範例改寫後,獲得以下程式碼 (model.py):
>
> from turboentity import *
> from docutils.core import publish_parts
>
> class Post(Entity):
> class turboentity:
> tablename = "posts"
>
> title = Column(Unicode(50))
> content = Column(Unicode)
> post_date = Column(DateTime, default=datetime.now())
> is_published = Column(Boolean, default=False)
> comments = OneToMany('Comment',backref='posts')
>
> @property
> def html_content(self):
> return publish_parts(self.content,writer_name="html")["html_body"]
>
> class Comment(Entity):
> class turboentity:
> tablename = "comments"
>
> author_name = Column(Unicode(255), nullable=False)
> author_email = Column(Unicode(255), nullable=False)
> author_url = Column(String(255))
> comment_date = Column(DateTime, default=datetime.now())
> content = Column(Unicode)
> post = ManyToOne("Post",backref='comments')
>
要表示 post-comments 關係只需分別在兩個類別中宣告 OneToMany - ManyToOne 即可,真是方便呀.
另外當定義好 TurboEntity 類別後,物件自動可以用傳值的方式輸入內容,不需一個個各別指定喔.
例如一般的寫法是這樣子:
p = Post.get (1) # 取得條目 c = Comment () # 新建一條評論 c.post = p # 這條評論屬於 p 條目 c.author_name = "CommentDude1" # 這條目的作者是 c.author_email = "[email protected]" # 這條目作者的郵件信箱是 c.content = "Great post! Keep them coming!" # 這條目的內容 c.flush () 可以直接改成 p = Post.get (1) c = Comment (post=post, author_name="Bob", author_email="[email protected]", content="Bob loves this site.", author_url="http://bob.example.com/") c.flush()
用TurboEntity改寫的程式和原本 Tutorial 相比,可以看出它好用的地方.
如何在 Blogger (Blogspot) 上使用 UrMap API
<script type="text/javascript"> function map_details() { var map = new UMap(document.getElementById("urmap")); map.setCenter(new ULatLng(25.035405, 121.520255), 9);}</script>
參考這篇講如何在 Blooger 上使用 GoogleMap API 的文章, 試著使用 UrMap API 來看看能不能用.
目前的嘗試好像不太成功的樣子 Orz
TurboGears vs Rails
明天公司補放國父誕辰紀念日,所以有空到 Google 翻翻最近有沒什麼有趣的文章。我找到了一篇 TurboGears vs Rails. 文章名稱夠聳動,雖然這篇文章有點舊了 (用的是 0.9 的預覽版 TurboGears, 或稱為未進化型態版本 XD), 不過裡面對 TurboGears 和 Rails 的特性確實抓得頗準:
The Pythonic way is "explicit over implicit". Everything is out for show: you know what modules are imported, you know what methods are exposed, you know what columns are defined and so on. It may take more keystrokes but the extra code let's you know what is happening when things go wrong. python 語言的風格是 '直率的比含糊的好'. 所以所有的過程都可以被檢視:妳曉得如何導入使用的模組,函式怎麼對應到網址上,妳也曉得資料物件如何定義等等。妳可能需要多打一些字 (註:事實上不多), 但是這些額外的程式碼能讓妳在發生錯誤時更容易地知道自己的程式到底發生了什麼事.
The the Rails way is the opposite: take the burden off the developer, don't bother them with the petty details that get in the way and add to the line noise. Rails 的寫作方式則相反:把讓開發者困擾的因子都去除掉,不要在開發中用細節來干擾程式碼.
事實上去年 5 月底時,我在看過 OnLamp 網站上的 Ruby On Rails 教學後,相當驚訝現在網頁開發的進步 (之前有一年沒寫動態網頁了). 所以我也趁等待完成論文前的時間歔空寫了篇 Ruby On Rails 教學。不過在 7 , 8 月 Django, TurboGears 這些 Python 框架相繼出現後,我發現除了可以使用熟悉的 Python 語言風格來寫程式之外,以後也可以透過網頁介面來使用大量的 Python 模組實在非常吸引我。而當 TurboGears 框架出現 ToolBox 這神奇的工具箱後,我開始漸漸投入了 TurboGears 開發的行列.
能展現自我特點的是創意而不是程式碼 在我的觀念裡,能展現自我特點的是創意而不是程式碼 (也許因為我不是個天才程式設計師吧 XD). Rails 也是個相當吸引人的框架 (差不多靠一己之力拉拔 Ruby 語言 XD). 但是 python 的 "應該會有一個 -- 最適當的一個的方式來實現" 哲學比較接近我的想法。在閱讀其他人的 TurboGears 專案時只要不用到太進階的 Python 語言功能,基本上都非常易於閱讀與修改. (例如目前 TurboGears 最進階的教學文件: SQLalchemy 版的 SimpleBlog, 花一些時間就可以改寫成 TurboEntity 版 SimpleBlog 之一, 之二)
淺談網頁框架的 URL 對映
當開始使用 MVC (Model, View, Controller) 的方式設計網站程式後,組織網站架構的重任就從傳統的分頁換到程式控制部份 (Controller) 的網址 - 函式對映 (URL Mapper) 上.
舉 python 網頁框架的例子為例,python 的網頁框架很多,最常聽到的 Django, TurboGears, pylons 都各自有各自不同的網址 - 函式對映方式. 網址 - 函式對映能將程式控制部份對映到網站架構,也能依照一些規則將輸入的網址對應成函式的參數,方便程式使用.
Colubrid 這個 WSGI 工具的網站上清楚地列出了目前常見的 URL 對映分類:
- 使用 正則表達式 (Regular Expression, Regex) 對映 -Django
- 使用 物件 (Object) 對映 -TurboGears
- 使用 路徑 (Routes) 對映 -pylons
"-" 號後面的補註是我另加上去的,表示這幾個框架預設的 URL 對映方式. 當然有的框架也可以用另外的 URL 對映 (例如 TurboGears 也能使用路徑對應方式).
範例
首先我們先給出一個基本的程式架構,再來討論如何將這個程式對應到網頁上。本文隱藏了各網頁框架特定的程式碼,因此在實際運行各種對應方式時需要再加上各自的程式碼.
Class Root(object):
def index(self):
return "Front Page"
def profile(self):
return "Profile Page"
app = Root()
這個類別 (Class) 包含兩個函式 (Method), 我們的目的是讓它顯示成如下的網站架構:
/
- index
- profile
例子很淺顯,我們就開始來嘗試吧
1. 使用 正則表達式 (Regular Expression) 對映
使用時在 Root 類別裡加上正則表達式來對映網頁
urls = [
(r'^index,'index'),
(r'^profile,'profile')
]
網頁架構是一串以 (r' 網頁名稱 ' ,' 函式名稱 ') 組成的列表來定義. 網頁名稱,函式名稱部份都可以使用正則表達式
2. 使用 物件對映
不必加入特別的對映方式. Root 類別在實例化後等同網站預設的根目錄, Root 類別下的兩個函式直接對映到相應名稱的網頁上.
/- Root
- index()
- profile()
訪問 / 或 /index 時就等於訪問 index () 函式, 訪問 /profile 時就等於訪問 profile () 函式
3. 使用 路徑對映
這種方式是跟 Ruby on Rails 學來的. 方法是另外建立一個類別,專門處理網頁架構.
class app(RoutesApplication):
mapping = [
('/', Root.index),
('/profile', Root.profile)
]
app = app()
網頁架構是以 (' 網頁名稱 ' ,' 類別。函式名稱 ') 組成的列表來定義. 網頁名稱部份可以使用正則表達式.
結語
我在寫本篇之前,從來沒有看懂其他網頁框架的對應方式,因此傻瓜式的物件對映方式對我來說是最直覺了,使用至今還沒什麼感到不方便的地方.
雖然本篇所作的比較簡單,無法展現各種對映方式的實際能力, 例如本篇沒有比較到輸入參數的對映方式.
以上三種方法都已經被證明有效而且許多網站正使用著這些方法運行著. 希望大家能以本篇為基礎,就較理解的 URL 對映方式繼續深入學習.
我很想知道各位看官,對於用簡單的例子來對的各種 URL 對映方式做說明是不是比較容易理解呢?