python web.py詳解
你知道Python同時你希望製作一個網站。 那麼web.py正好提供了一種簡單的方法。 詳細,可以檢視官方文件:http://webpy.org/
如果你已經有了一個web.py專案,請看看升級 頁面的相關資訊。
準備開始。
URL 處理
任何網站最重要的部分就是它的URL結構。你的URL並不僅僅只是訪問者所能看到並且能發給朋友的。它還規定了你網站執行的心智模型。在一些類似del.icio.us的流行網站 , URL甚至是UI的一部分。 web.py使這類強大的URL成為可能。
在開始你的web.py程式之前,開啟一個文字檔案(檔名為code.py)輸入:
import web
這條語句會匯入web.py模組。
現在我們需要把我們的URL結構告訴web.py。讓我從下面這個簡單的例子開始:
urls = (
'/', 'index',
)
第一部分是匹配URL的正則表示式,像/、/help/faq、/item/(\d+)等(\d+將匹配數字)。圓括號表示捕捉對應的資料以便後面使用。第二部分是接受請求的類名稱,像index、view、welcomes.hello (welcomes模組的hello類),或者get_\1。\1 會被正則表示式捕捉到的內容替換,剩下來捕捉的的內容將被傳遞到你的函式中去。
這行表示我們要URL/(首頁)被一個叫index的類處理。
現在我們需要建立一個列舉這些url的application。
app = web.application(urls, globals())
這會告訴web.py去建立一個基於我們剛提交的URL列表的application。這個application會在這個檔案的全域性名稱空間中查詢對應類。
GET和POST: 區別
現在我們需要來寫index類。雖然大多數人只會看看,並不會注意你的瀏覽器在使用用於與全球資訊網通訊的HTTP語言。具體的細節並不重要,但是要理解web訪問者請求web伺服器去根據URL(像/、/foo?f=1)執行一個合適的函式(像GET、POST)的基本思想。
GET是我們都熟悉的。它用於請求網頁文字。當你在瀏覽器輸入harvard.edu,它會直接訪問Harvard的web伺服器,去GET /。 第二個最有名的是POST,它經常被用在提交form,比如請求買什麼東西。每當提交一個去做什麼事情(像使用信用卡處理一筆交易)的請求時,你可以使用POST。這是關鍵,因為GET的URL可以被搜尋引擎索引,並通過搜尋引擎訪問。雖然大部分頁面你希望被索引,但是少數類似訂單處理的頁面你是不希望被索引的 (想象一下Google嘗試去購買你網站上的所有東西)。
在我們web.py的程式碼中,我們將這兩個方法明確區分:
class index:
def GET(self):
return "Hello, world!"
當有人用GET請求/時,這個GET函式隨時會被web.py呼叫。
好了,限制我們只需要最後一句就寫完了。這行會告訴web.py開始提供web頁面:
if __name__ == "__main__": app.run()
這會告訴web.py為我們啟動上面我們寫的應用。
現在注意,即使我已經在這裡說了很多,但我們真正有5行這些程式碼。這就是你需要編寫的一個完整的web.py應用。 為了更方便的使用,你的完整程式碼應該像下面這樣:
import web
urls = (
'/', 'index'
)
class index:
def GET(self):
return "Hello, world!"
if __name__ == "__main__":
app = web.application(urls, globals())
app.run()
啟動服務
現在你的web.py應用正執行在你電腦上的一個真正的web伺服器上。 訪問那個URL,然後你應該看到”Hello, world!” (你可以通過把IP地址/埠加在”code.py”的後面,來控制web.py在哪裡啟動伺服器。你也可以讓它執行在fastcgi或scgi伺服器上)。
注意: 如果你不能或者不想使用預設埠,你可以使用這樣的命令來指定埠號:
$ python code.py 1234
模板
在 Python 中寫 HTML 不是聰明的選擇,相反在 HTML 中寫 Python 則有趣的多。幸運的是,web.py 讓這件事情做得簡單而又漂亮。
注意: 老版本的 web.py 使用 Cheetah 模板系統,你可以也歡迎使用其他模板系統,但它可能不會被長久支援。
給模板新建一個目錄(命名為 templates),在該目錄下新建一個以 .html 結尾的檔案,內容如下:
<em>Hello</em>, world!
你也可以在模板中使用 web.py 模板支援程式碼:
$def with (name)
$if name:
I just wanted to say <em>hello</em> to $name.
$else:
<em>Hello</em>, world!
如上,該模板看起來就像 python 檔案一樣,除了頂部的 def with (表示從模板將從這後面取值)和總是位於程式碼段之前的$
。當前,template.py 首先請求模板檔案的首行$def
。當然,你要注意 web.py 將會轉義任何任何用到的變數,所以當你將 name 的值設為是一段 HTML 時,它會被轉義顯示成純文字。如果要關閉該選項,可以寫成 $:name 來代替 $name。
回看再看 code.py。在第一行之下新增:
render = web.template.render('templates/')
這會告訴web.py到你的模板目錄中去查詢模板。若報錯找不到摸板檔案,可以嘗試把路徑改為絕對路徑。然後把 index.GET改成: 告訴 web.py 在你的模板目錄下查詢模板檔案。修改 index.GET :
name = 'Bob'
return render.index(name)
(’index’ 是模板的名字,’name’ 是傳入模板的一個引數)
訪問站點它將顯示 hello Bob。
但是如果我們想讓使用者自行輸入他的名字,麼辦?如下:
i = web.input(name=None)
return render.index(i.name)
訪問 / 將顯示 hello world,訪問 /?name=Joe 將顯示 hello Joe。
URL 的後面的 ? 看起來不好看?修改下 URL 配置:
'/(.*)', 'index'
然後修改下 index.GET:
def GET(self, name):
return render.index(name)
現在訪問 /Joe 看看,它會顯示 hello Joe。
如果學習更多關於 web.py 的模板處理,請訪問 web.py 模板.
表單
web.py的form模組能夠幫助你生成HTML表單;獲取使用者的輸入,並在處理或新增到資料庫之前對其進行內容的驗證。 如果你要學習更多關於form模組的使用,請檢視幫助文件或者Form類庫的連結
資料庫操作
注意: 在你開始使用資料庫之前,確保你已經安裝了合適的資料庫訪問庫。比如對於MySQL資料庫,使用 MySQLdb ,對於Postgres資料庫使用psycopg2。
首先你需要建立一個數據庫物件。
db = web.database(dbn='postgres', user='username', pw='password', db='dbname')
(根據需要修改這裡 – 尤其是username 、 password 、 dbname – 。 MySQL使用者還需要把 dbn 定義改為 mysql。)
這就是所有你需要做的 – web.py將會自動處理與資料庫的連線和斷開。
使用的的資料庫引擎管理工具,在你的庫中建立一個簡單的表:
CREATE TABLE todo (
id serial primary key,
title text,
created timestamp default now(),
done boolean default 'f' );
然後初始化行:
INSERT INTO todo (title) VALUES ('Learn web.py');
我們回來繼續編輯 code.py ,把 index.GET 改成下面的樣子,替換整個函式:
def GET(self):
todos = db.select('todo')
return render.index(todos)
然後把URL列表改回來,只保留 /:
'/', 'index',
像這樣編輯並替換 index.html 的全部內容:
$def with (todos)
<ul>
$for todo in todos:
<li id="t$todo.id">$todo.title</li>
</ul>
再訪問你的網站,然後你可以看到你的todo item: “Learn web.py”。恭喜你!你已經完整地寫好了一個可以從資料庫讀取資料的程式。現在讓我們同樣再寫一個可以把資料寫入資料庫的程式。
在 index.html尾部新增:
然後把你的URL列表改為:
'/', 'index',
'/add', 'add',
(你必須要非常小心那些逗號。如果你省略他們,Python會把所有字串連線起來,變成 ‘/index/addadd’)
現在新增另一個類:
class add:
def POST(self):
i = web.input()
n = db.insert('todo', title=i.title)
raise web.seeother('/')
(注意現在我們正在使用 POST)
web.input 可以讓你訪問使用者通過form提交的任何資料。
注意: 如果要訪問多個相同名字的欄位,請使用list的格式(比如:一串name=”name”的多選框):
post_data=web.input(name=[])
db.insert 把資料插入資料表 todo ,然後把新的行號返回給你。 seeother 把使用者重定向到指定的URL。
一些快速補充說明: db.update 與 db.insert 差不多,除了它返回的行號是直接從sql語句裡面提取的(WHERE ID=2)。
web.input、 db.query已經其他web.py中的函式返回”Storage objects”,這些東西就像字典,你除了可以 d[‘foo’]之外,你還可以 d.foo。這可以讓程式碼更加乾淨。
你可以在the documentation找到這方面具體的細節以及所有web.py的函式說明。
除錯
web.py 還有一些幫助我們debug的工具。當它在內建的伺服器中執行時,它會一debug模式啟動程式。在debug模式中,任何程式碼、模板的修改,都會讓伺服器重新載入它們,然後還會輸出有用的錯誤訊息。
只有在生產環境中debug模式是關閉的。如果你想禁用debug模式,你可以在建立程式/模板前新增像這樣的行。
web.config.debug = False