在文章《基於Linux環境搭建Nginx+uWSGI+Python框架方法介紹》中介紹了客戶端和Web服務器的交互過程,Web服務器接收客戶端的請求後,由Web應用服務器對瀏覽器的請求進行處理,將生成的響應傳遞給Web服務器,再由Web服務器返回給客戶端。爲了簡化Web網站的開發,使開發者能夠專一於編寫業務邏輯代碼而無需關心Web應用服務器內各模塊鏈接之類的重複性工做,繼而在Web應用服務器上產生了Web框架。通常Web框架的架構以下圖所示,基於Python的Web框架如Django、tornado、flask、webpy等都在這個範圍內進行不一樣的調整。html
MVC是衆所周知的Web框架設計模式,即將應用程序分解成model(模型)、view(視圖)和 controller(控制器)三個組成部分。用戶輸入 URL,客戶端發送請求,控制器(Controller)首先會拿到請求,而後用模型(Models)從數據庫取出全部須要的數據進行必要的處理,將處理後的結果發送給視圖(View),視圖利用獲取到的數據進行渲染生成 Html返回給客戶端。MVC設計模式將業務邏輯、數據、界面顯示分離,業務邏輯彙集到一個模塊中,使得在更改界面時無需從新編寫業務邏輯,提升網站的維護性。python
相較與大而全的Django框架來講很是輕量級的開源Python Web框架Web.py,它小巧靈活、簡單而且強大,在使用時沒有任何限制。目前Web.py被普遍運用於大型網站,如西班牙的社交網站Frinki、主頁日平均訪問量達7000萬次的Yandex等。下面經過Get和Post實現例程來介紹下Web.py的應用。web
1) web.py的安裝正則表達式
web.py下載地址:http://webpy.org/static/web.p...。解壓並拷貝web.py-0.38文件夾到目錄下運行:數據庫
python setup.py install(sudo python setup.py install)
2)Python例程——GETflask
在Web.py中URL的請求映射於urls元組中,元組結構第一部分爲匹配URL的正則表達式,第二部分爲接受請求的類名稱。app= web.application(urls, globals())建立一個列舉URL列表的應用,該應用會在文件的全局命名空間中查找對應類。如'/'徹底匹配URLhttp://0.0.0.0:8080/;'/task/d'匹配'/task/'開頭然後爲任意1個數字的URL;'/(.*)'匹配'/'後任意內容做爲參數返回,類中需有參數接收。segmentfault
在Html代碼中使用了Web.py支持的模板引擎Templetor,模板引擎的用途是使界面與數據分離,界面模板通過模板引擎的渲染後會生成最終的界面文件。如第一行$def with (name)定義了一個變量name;$name會用name的值來替換。設計模式
templates目錄下存放.html模板文件,render = web.template.render('templates/') 生成render會從模板目錄查找文件,render.hello(..)表示渲染 hello.html 模板。瀏覽器
固然Web.py也支持使用Jinja2模板引擎,因爲Jinja2屬於第三方庫須要單獨安裝,在py文件中執行render = render_jinja('templates',encoding = 'utf-8')更換爲Jinja2模板引擎,在html文件中可按照Jinja2支持的語法進行編寫,這樣就能使用jinja2模板引擎進行渲染。服務器
Python代碼:
import web render = web.template.render('templates/') urls = ( '/', 'hello', #徹底匹配 '/task/\d', 'task', #模糊匹配 '/(.*)', 'anyd' #帶組匹配 正則表達式(.*)匹配/後任意內容並做爲參數返回,類中需有參數接收 ) class anyd: def GET(self,name): i=web.input(name=None) return render.index(name) class hello: def GET(self): return "Hello, world!" class task: def GET(self): name='Bob' return render.index(name) if __name__ == "__main__": app = web.application(urls, globals()) app.run()
html代碼:
$def with (name)#定義了一個變量 name $if name: I just wanted to say <em>hello</em> to $name. $else: <em>Hello</em>, world!
將py文件保存爲mywebpy.py,web.py內置了web服務器,運行後顯示http://0.0.0.0:8080/即啓動了服務器。在瀏覽器中輸入http://127.0.0.1:8080會顯示Hello,world!,在瀏覽器中輸入http://127.0.0.1:8080/task/1會顯示I just wanted to say hello to Bob, 在瀏覽器中輸入http://127.0.0.1:8080/Tom顯示I just wanted to say hello to Tom
注:在調試中ps查看web服務器進程ID,kill當前進程後才能從新啓動服務器,不然會提示No socket could be created錯誤
3) Python例程——POST
Web.py中'web.form'模塊支持表單的建立、校驗和顯示。該模塊包含一個'Form'對象和各類輸入框類如Textbox、Password 、Textarea 、Dropdown、Radio、Checkbox、Button等。 Form對象的validates方法能夠驗證Form對象中inputs是否有效。只有調用了validates方法,Form對象的各個inputs纔會有相應的值,不然其值均爲None。validates方法內部默認會使用web.input()來做爲數據來源去驗證,也可使用source參數指定數據來源。一樣可使用Form對象中Validator來校驗表單。如下例程中在填寫表格Post提交後,若是password和password_again值相同,那麼會顯示'HAHA!',不然顯示'Try again, Passwords didn't match:'。
Python代碼:
import web,os from web import form render = web.template.render("templates") urls = ( '/', 'index', ) app = web.application(urls, globals()) login = form.Form( form.Textbox('username'), form.Password('password'), form.Password('password_again'), form.Checkbox('YES'), form.Checkbox('NO'), form.Textarea('Moe'), form.Dropdown('SEX', ['man', 'woman']), form.Radio('time',['2012-01-01','20120101']), form.Button('Login'), validators = [form.Validator("Passwords didn't match.", lambda i: i.password == i.password_again)] ) class index: def GET(self): f=login() return render.formtest(f) def POST(self): f=login() if not f.validates(): return render.formtest(f) else: return "HAHA!" if __name__ == "__main__": web.internalerror = web.debugerror app.run()
html代碼:
$def with (form) <form name="main" method="post"> $if not form.valid: <p class="error">Try again,Passwords didn't match:</p> $:form.render() <input type="submit" /></form>