1. 程式人生 > >python web.py詳解

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