python網(wǎng)絡(luò)編程學(xué)習(xí)筆記(10):webpy框架
django和webpy都是python的web開(kāi)發(fā)框架。Django的主要目的是簡(jiǎn)便、快速的開(kāi)發(fā)數(shù)據(jù)庫(kù)驅(qū)動(dòng)的網(wǎng)站。它強(qiáng)調(diào)代碼復(fù)用,多個(gè)組件可以很方便的以“插件”形式服務(wù)于整個(gè)框架,Django有許多功能強(qiáng)大的第三方插件,你甚至可以很方便的開(kāi)發(fā)出自己的工具包。這使得Django具有很強(qiáng)的可擴(kuò)展性。它還強(qiáng)調(diào)快速開(kāi)發(fā)和DRY(Do Not Repeat Yourself)原則。webpy小巧,簡(jiǎn)單,實(shí)用,可以快速的完成簡(jiǎn)單的web頁(yè)面。這里根據(jù)webpy Cookbook簡(jiǎn)要的介紹一下webpy框架,更加詳細(xì)請(qǐng)見(jiàn)http://webpy.org/cookbook/index.zh-cn。
一、安裝與開(kāi)發(fā)
web.py下載地址:http://webpy.org/static/web.py-0.33.tar.gz。解壓并拷貝web文件夾到你的應(yīng)用程序目錄下?;蛘撸瑸榱俗屗械膽?yīng)用程序都可以使用,運(yùn)行:
python setup.py install
注意: 在某些類unix系統(tǒng)上你可能需要切換到root用戶或者運(yùn)行:
sudo python setup.py install
也可以直接把里面的WEB文件夾放site-packages 。
web.py 內(nèi)置了web服務(wù)器,代碼寫(xiě)完后,將其保存,例如文件名為mywebpy.py,可以用下面的方法來(lái)啟動(dòng)服務(wù)器:
python mywebpy.py
打開(kāi)你的瀏覽器輸入 http://localhost:8080/ 查看頁(yè)面。 若要制定另外的端口,使用 python mywebpy.py 1234。
二、URL 處理
任何網(wǎng)站最重要的部分就是它的URL結(jié)構(gòu)。你的URL并不僅僅只是訪問(wèn)者所能看到并且能發(fā)給朋友的。它還規(guī)定了你網(wǎng)站運(yùn)行的心智模型。在一些類似del.icio.us的流行網(wǎng)站 , URL甚至是UI的一部分。 web.py使這類強(qiáng)大的URL成為可能。
urls = (
'/', 'index'
)
第一部分是匹配URL的正則表達(dá)式,像/、/help/faq、/item/(\d+)等(\d+將匹配數(shù)字)。圓括號(hào)表示捕捉對(duì)應(yīng)的數(shù)據(jù)以便后面使用。第二部分是接受請(qǐng)求的類名稱,像index、view、welcomes.hello (welcomes模塊的hello類),或者get_\1。\1 會(huì)被正則表達(dá)式捕捉到的內(nèi)容替換,剩下來(lái)捕捉的的內(nèi)容將被傳遞到你的函數(shù)中去。這行表示我們要URL/(首頁(yè))被一個(gè)叫index的類處理?,F(xiàn)在我們需要?jiǎng)?chuàng)建一個(gè)列舉這些url的application。
app = web.application(urls, globals())
這會(huì)告訴web.py去創(chuàng)建一個(gè)基于我們剛提交的URL列表的application。這個(gè)application會(huì)在這個(gè)文件的全局命名空間中查找對(duì)應(yīng)類。
一般來(lái)說(shuō),在每個(gè)應(yīng)用的最頂部,你通常會(huì)看到整個(gè)URL調(diào)度模式被定義在元組中:
urls = (
"/tasks/?", "signin",
"/tasks/list", "listing",
"/tasks/post", "post",
"/tasks/chgpass", "chgpass",
"/tasks/act", "actions",
"/tasks/logout", "logout",
"/tasks/signup", "signup"
)
這些元組的格式是: URL路徑, 處理類 。
你可以利用強(qiáng)大的正則表達(dá)式去設(shè)計(jì)更靈活的URL路徑。比如 /(test1|test2) 可以捕捉 /test1 或 /test2。要理解這里的關(guān)鍵,匹配是依據(jù)URL路徑的。比如下面的URL:
http://localhost/myapp/greetings/hello?name=Joe
這個(gè)URL的路徑是 /myapp/greetings/hello。web.py會(huì)在內(nèi)部給URL路徑加上和$ ,這樣 /tasks/ 不會(huì)匹配 /tasks/addnew。URL匹配依賴于“路徑”,所以不能這樣使用,如: /tasks/delete?name=(.+) ,?之后部分表示是“查詢”,并不會(huì)被匹配。閱讀URL組件的更多細(xì)節(jié),請(qǐng)?jiān)L問(wèn)web.ctx。
你可以捕捉URL的參數(shù),然后用在處理類中:
/users/list/(.+), "list_users"
在 list/后面的這塊會(huì)被捕捉,然后作為參數(shù)被用在GET或POST:
class list_users:
def GET(self, name):
return "Listing info about user: {0}".format(name)
你可以根據(jù)需要定義更多參數(shù)。同時(shí)要注意URL查詢的參數(shù)(?后面的內(nèi)容)也可以用web.input()取得。
三、hello world
現(xiàn)在我們需要來(lái)寫(xiě)index類。雖然大多數(shù)人只會(huì)看看,并不會(huì)注意你的瀏覽器在使用用于與萬(wàn)維網(wǎng)通信的HTTP語(yǔ)言。具體的細(xì)節(jié)并不重要,但是要理解web訪問(wèn)者請(qǐng)求web服務(wù)器去根據(jù)URL(像/、/foo?f=1)執(zhí)行一個(gè)合適的函數(shù)(像GET、POST)的基本思想。GET用于請(qǐng)求網(wǎng)頁(yè)文本。當(dāng)你在瀏覽器輸入harvard.edu,它會(huì)直接訪問(wèn)Harvard的web服務(wù)器,去GET /。 POST經(jīng)常被用在提交form,比如請(qǐng)求買什么東西。每當(dāng)提交一個(gè)去做什么事情(像使用信用卡處理一筆交易)的請(qǐng)求時(shí),你可以使用POST。這是關(guān)鍵,因?yàn)镚ET的URL可以被搜索引擎索引,并通過(guò)搜索引擎訪問(wèn)。雖然大部分頁(yè)面你希望被索引,但是少數(shù)類似訂單處理的頁(yè)面你是不希望被索引的。
在我們web.py的代碼中,我們將這兩個(gè)方法明確區(qū)分:
class index:
def GET(self):
return "Hello, world!"
當(dāng)有人用GET請(qǐng)求/時(shí),這個(gè)GET函數(shù)隨時(shí)會(huì)被web.py調(diào)用。
好了,限制我們只需要最后一句就寫(xiě)完了。這行會(huì)告訴web.py開(kāi)始提供web頁(yè)面:
if __name__ == "__main__": app.run()
這會(huì)告訴web.py為我們啟動(dòng)上面我們寫(xiě)的應(yīng)用。
于是將上面的代碼完整列出如下:
import web
urls = (
'/', 'index'
)
class index:
def GET(self):
return "Hello, world!"
if __name__ == "__main__":
app = web.application(urls, globals())
app.run()
保存為hello.py,運(yùn)行后顯示:
http://0.0.0.0:8080/
在瀏覽器中輸入http://127.0.0.1:8080,就會(huì)出現(xiàn)hello world!頁(yè)面。
四、模板
給模板新建一個(gè)目錄(命名為 templates),在該目錄下新建一個(gè)以 .html 結(jié)尾的文件,這里存為index.html,內(nèi)容如下:
<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!
如上,該模板看起來(lái)就像 python 文件一樣,除了頂部的 def with (表示從模板將從這后面取值)和總是位于代碼段之前的$。當(dāng)前,template.py 首先請(qǐng)求模板文件的首行 $def 。當(dāng)然,你要注意 web.py 將會(huì)轉(zhuǎn)義任何用到的變量,所以當(dāng)你將name的值設(shè)為是一段HTML時(shí),它會(huì)被轉(zhuǎn)義顯示成純文本。如果要關(guān)閉該選項(xiàng),可以寫(xiě)成 $:name 來(lái)代替 $name。
在code.py第一行之下添加:
render = web.template.render('templates/')
這會(huì)告訴web.py到你的模板目錄中去查找模板。然后把 index.GET改成: 告訴 web.py 在你的模板目錄下查找模板文件。修改 index.GET :
name = 'Bob'
return render.index(name)
完整代碼為:
##@小五義
import web
render = web.template.render('templates/')
urls = (
'/', 'index'
)
class index:
def GET(self):
name='Bob'
return render.index(name)
#return "Hello, world!"
if __name__ == "__main__":
app = web.application(urls, globals())
app.run()
訪問(wèn)站點(diǎn)它將顯示 I just wanted to say hello to Bob。
但是如果我們想讓用戶自行輸入他的名字,如下:
i = web.input(name=None)
return render.index(i.name)
訪問(wèn) / 將顯示 hello world,訪問(wèn) /?name=Joe 將顯示 I just wanted to say hello to Joe。
URL 的后面的 ? 看起來(lái)不好看,修改下 URL 配置:
'/(.*)', 'index'
然后修改下 GET:
def GET(self, name):
return render.index(name)
完整代碼為:
##@小五義
import web
render = web.template.render('templates/')
urls = (
'/(.*)', 'index'
)
class index:
def GET(self,name):
i=web.input(name=None)
return render.index(name)
#return "Hello, world!"
if __name__ == "__main__":
app = web.application(urls, globals())
app.run()
現(xiàn)在訪問(wèn)http://127.0.0.1:8080/TOM ,它會(huì)顯示I just wanted to say hello to TOM. 如果訪問(wèn)http://127.0.0.1:8080/,它會(huì)顯示Hello, world!
五、表單
1、簡(jiǎn)介
表單包括Textbox、Password 、Textarea 、Dropdown、Radio、Checkbox、Button具體使用及樣式如下:
login = form.Form(
form.Textbox('username'),
form.Password('password'),
form.Password('password_again'),
form.Button('Login'),
form.Checkbox('YES'),
form.Checkbox('NO'),
form.Textarea('moe'),
form.Dropdown('SEX', ['man', 'woman']),
form.Radio('time',['2012-01-01','20120101']),
validators = [form.Validator("Passwords didn't match.", lambda i: i.password == i.password_again)]
)
顯現(xiàn)在頁(yè)面中:
2、輸入屬性
如:
form.textbox("firstname",
form.notnull, #put validators first followed by optional attributes
class_="textEntry", #gives a class name to the text box -- note the underscore
pre="pre", #directly before the text box
post="post", #directly after the text box
description="please enter your name", #describes field, defaults to form name ("firstname")
value="bob", #default value
id="nameid", #specify the id
)
3、例子:
##code.py
##@小五義
import web,os
from web import form
render = web.template.render("d:/webpy/templates")##這里仿照http://webpy.org/form#example最初使用了相對(duì)路徑templates/,但總是發(fā)生找不到formtest的錯(cuò)誤,于是搜索后,發(fā)現(xiàn)換成絕對(duì)路徑可以解決這一問(wèn)題。
urls = (
'/', 'index',
)
app = web.application(urls, globals())
login = form.Form(
form.Textbox('username'),
form.Password('password'),
form.Password('password_again'),
form.Button('Login'),
form.Checkbox('YES'),
form.Checkbox('NO'),
form.Textarea('moe'),
form.Dropdown('SEX', ['man', 'woman']),
form.Radio('time',['2012-01-01','20120101']),
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()
d:/webpy/templates文件夾下存放formtest.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>
運(yùn)行code.py,然后在瀏覽器中瀏覽頁(yè)面如下:
填寫(xiě)表格后,如果兩次password相同,那么會(huì)顯示HAHA!,否則顯示Try again, Passwords didn't match:。
六、數(shù)據(jù)庫(kù)
1、數(shù)據(jù)庫(kù)的連接
在開(kāi)始使用數(shù)據(jù)庫(kù)之前,確保已經(jīng)安裝了合適的數(shù)據(jù)庫(kù)訪問(wèn)庫(kù)。比如對(duì)于MySQL數(shù)據(jù)庫(kù),使用 MySQLdb ,對(duì)于Postgres數(shù)據(jù)庫(kù)使用psycopg2。
創(chuàng)建一個(gè)數(shù)據(jù)庫(kù)對(duì)象:db = web.database(dbn='postgres', user='username', pw='password', db='dbname')
2、數(shù)據(jù)庫(kù)讀取
例,在數(shù)據(jù)庫(kù)test中有一個(gè)表testtable,字段是name,在上面code.py中進(jìn)行修改,如果login成功,那么列出test表中的內(nèi)容。
code.py
##@小五義
import web,os
from web import form
db = web.database(dbn='postgres', user='postgres', pw='password', db='test')
render = web.template.render("d:/webpy/templates")
urls = (
'/', 'index',
)
app = web.application(urls, globals())
login = form.Form(
form.Textbox('username'),
form.Password('password'),
form.Password('password_again'),
form.Button('Login'),
form.Checkbox('YES'),
form.Checkbox('NO'),
form.Textarea('moe'),
form.Dropdown('SEX', ['man', 'woman']),
form.Radio('time',['2012-01-01','20120101']),
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:
testtables = db.select('testtable')
return render.index(testtables)
if __name__ == "__main__":
web.internalerror = web.debugerror
app.run()
##index.html
$def with (testtables)
<ul>
$for testtable in testtables:
<li id="t$testtable.name">$testtable.name</li>
</ul>
當(dāng)login正確后,會(huì)列出testtable表中name字段的值。
3、數(shù)據(jù)庫(kù)寫(xiě)入
如將上面的FORM表中的user加入到testtable表name字段中,很簡(jiǎn)單,只需要在上面的代碼中加入一句:n=db.insert('voa',filename=f['username'].value)。
現(xiàn)在,對(duì)code.py代碼進(jìn)行修改后,當(dāng)表單填寫(xiě)正確后,會(huì)將username加入到testtable表中,完整代碼如下:
##@小五義
import web,os
from web import form
db = web.database(dbn='postgres', user='postgres', pw='password', db='bbstime')
render = web.template.render("d:/webpy/templates")
urls = (
'/', 'index',
)
app = web.application(urls, globals())
login = form.Form(
form.Textbox('username'),
form.Password('password'),
form.Password('password_again'),
form.Button('Login'),
form.Checkbox('YES'),
form.Checkbox('NO'),
form.Textarea('moe'),
form.Dropdown('SEX', ['man', 'woman']),
form.Radio('time',['2012-01-01','20120101']),
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:
n=db.insert('voa',filename=f['username'].value)
voas = db.select('voa')
return render.index(voas)
if __name__ == "__main__":
web.internalerror = web.debugerror
app.run()
相關(guān)文章
Python爬蟲(chóng)模擬登陸嗶哩嗶哩(bilibili)并突破點(diǎn)選驗(yàn)證碼功能
這篇文章主要介紹了Python爬蟲(chóng)模擬登陸嗶哩嗶哩(bilibili)并突破點(diǎn)選驗(yàn)證碼功能,本文通過(guò)圖文實(shí)例相結(jié)合給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-12-12Python功能點(diǎn)實(shí)現(xiàn):函數(shù)級(jí)/代碼塊級(jí)計(jì)時(shí)器
今天小編就為大家分享一篇關(guān)于Python功能點(diǎn)實(shí)現(xiàn):函數(shù)級(jí)/代碼塊級(jí)計(jì)時(shí)器,小編覺(jué)得內(nèi)容挺不錯(cuò)的,現(xiàn)在分享給大家,具有很好的參考價(jià)值,需要的朋友一起跟隨小編來(lái)看看吧2019-01-01Python OpenCV讀取視頻報(bào)錯(cuò)的問(wèn)題解決
大家好,本篇文章主要講的是Python OpenCV讀取視頻報(bào)錯(cuò)的問(wèn)題解決,感興趣的同學(xué)趕快來(lái)看一看吧,對(duì)你有幫助的話記得收藏一下2022-01-01Python yield生成器和return對(duì)比代碼實(shí)例
這篇文章主要介紹了Python yield生成器和return對(duì)比代碼實(shí)例,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-04-04如何用python合并多個(gè)有規(guī)則命名的nc文件
在地學(xué)領(lǐng)域,nc格式的文件可謂隨處可見(jiàn),這種文件可以存儲(chǔ)多維數(shù)字矩陣,下面這篇文章主要給大家介紹了關(guān)于如何用python合并多個(gè)有規(guī)則命名的nc文件的相關(guān)資料,需要的朋友可以參考下2022-03-03PyCharm之如何設(shè)置自動(dòng)換行問(wèn)題
這篇文章主要介紹了PyCharm之如何設(shè)置自動(dòng)換行問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-05-05Python異步處理返回進(jìn)度——使用Flask實(shí)現(xiàn)進(jìn)度條
這篇文章主要介紹了Python異步處理返回進(jìn)度——使用Flask實(shí)現(xiàn)進(jìn)度條,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-05-05pycharm中TensorFlow調(diào)試常見(jiàn)問(wèn)題小結(jié)
本文主要介紹了在pycharm下調(diào)用tensorflow庫(kù)時(shí)會(huì)出現(xiàn)的問(wèn)題,在本文做個(gè)小結(jié),也給自己留個(gè)筆記,感興趣的可以了解一下2021-06-06Python (Win)readline和tab補(bǔ)全的安裝方法
今天小編就為大家分享一篇Python (Win)readline和tab補(bǔ)全的安裝方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2019-08-08