2018年3月12日星期一

简单而直接的Python web 框架:web.py

From:https://www.oschina.net/question/5189_4306
Web.py github 地址:https://github.com/webpy/webpy        https://pypi.python.org/pypi/web.py
Web.py Cookbook 简体中文版:http://webpy.org/cookbook/index.zh-cn
web.py 0.3 新手指南:http://webpy.org/docs/0.3/tutorial.zh-cn
webpy 官网文档:http://webpy.org/
web.py 十分钟创建简易博客:http://blog.csdn.net/freeking101/article/details/53020728
一个简单的web.py论坛:http://www.cnblogs.com/russellluo/p/3240564.html

web.py 是一个Python 的web 框架,它简单而且功能强大。web.py 是公开的,无论用于什么用途都是没有限制的。而且相当的小巧,应当归属于轻量级的web 框架。但这并不影响web.py 的强大,而且使用起来很简单、很直接。在实际应用上,web.py 更多的是学术上的价值,因为你可以看到更多web 应用的底层,这在当今“抽象得很好”的web 框架上是学不到的 :) 如果想了解更多web.py,可以访问web.py 的官方文档。
先感受一下web.py 的简单而强大:
[python] view plain copy
  1. import web  
  2.   
  3. urls = (  
  4.     '/(.*)''hello'  
  5. )  
  6.   
  7. app = web.application(urls, globals())  
  8.   
  9. class hello:  
  10.     def GET(self, name):  
  11.         i = web.input(times=1)  
  12.         if not name:   
  13.             name = 'world'  
  14.         for c in xrange(int(i.times)):   
  15.             print 'Hello,', name+'!'  
  16.         return 'Hello, ' + name + '!'  
  17.   
  18. if __name__ == "__main__":  
  19.     app.run()  
上面就是一个基于web.py 的完整的Web 应用。将上面的代码保存为文件code.py,在命令行下执行python code.py。然后打开你的浏览器,打开地址:http://localhost:8080 或者 http://localhost:8080/test 没有意外的话(当然要先安装web.py,下面会有介绍),浏览器会显示“Hello, world”或者 Hello, test


Linux 下运行

这是一个最简单的Hello world Web 应用。是不是很简单?!下面将较为详细地介绍下web.py 。

1. 安装

下载 web.py 的安装文件,将下载得到的文件 web.py 解压,进入解压后的文件夹,在命令行下执行:python setup.py install,在Linux 等系统下,需要root 的权限,可以执行:sudo python setup.py install。

2. URL 处理

对于一个站点来说,URL 的组织是最重要的一个部分,因为这是用户看得到的部分,而且直接影响到站点是如何工作的,例如:www.baidu.com ,其URLs 甚至是网页界面的一部分。而web.py 以简单的方式就能够构造出一个强大的URLs。
在每个web.py 应用,必须先import web 模块:
[python] view plain copy
  1. import web  
现在,我们须要告诉web.py URL 如何组织,让我们以一个简单例子开始:
[python] view plain copy
  1. urls = (  
  2.   '/''index'    )  
在上面的例子中,第一部分是匹配URL的正则表达式,像//help/faq/item/(\d+)等(\d+将匹配数字)。圆括号表示捕捉对应的数据以便后面使用。第二部分是接受请求的类名称,像indexviewwelcomes.hello(welcomes模块的hello类),或者get_\1\1 会被正则表达式捕捉到的内容替换,剩下来捕捉的的内容将被传递到你的函数中去。(‘index’)是一个类名,匹配的请求将会被发送过去。这行表示我们要URL/(首页)被一个叫index的类处理。
现在我们需要创建一个列举这些 url 的 application。
[python] view plain copy
  1. app = web.application(urls, globals())  

GET 和 POST : 区别
现在,我们需要编写index 类。当大部人浏览网页的时候,他们都没有注意到,浏览器是通过HTTP 跟World Wide Web 通信的。通信的细节不太重要,但要明白一点,用户是通过URLs(例如 / 或者 /foo?f=1)来请求web 服务器完成一定请求的(例如 GET 或者POST)。
GET 是最普遍的方法,用来请求一个页面。当我们在浏览器里输入“harvard.edu” 的时候,实际上它是向Web 服务器请求GET ”/“。另一个常见的方法是POST,常用于提交特定类型的表单,比如请求买什么东西。每当提交一个去做什么事情(像使用信用卡处理一笔交易)的请求时,你可以使用POST。这是关键,因为GET的URL可以明文传输提交的参数。如果提交的是一些重要的敏感信息,例如用户名,密码,则可能被别人抓包获取到。而 POST 则不会在 URL 上传输 提交的信息,POST 是通过表单提交信息。
在我们的web.py 代码中。我们清晰区分这两种方法:
[python] view plain copy
  1. class index:  
  2.     def GET(self):  
  3.         print "Hello, world!"  
当接收到一个GET 请求时,上面的GET 方法将会被web.py 调用。好的。现在,我们只需添加最后一行代码,让web.py 启动网页应用:
[python] view plain copy
  1. if __name__ == "__main__":  
  2.     app.run()  
上面告诉web.py 如何配置URLs,以及找寻的类在文件中的全局命名空间。然后为我们启动上面的应用。
整个 code.py 文件的内容如下:
[python] view plain copy
  1. import web  
  2.   
  3. urls = (  
  4.     '/(.*)''hello'  
  5. )  
  6.   
  7. app = web.application(urls, globals())  
  8.   
  9. class hello:  
  10.     def GET(self, name):  
  11.         i = web.input(times=1)  
  12.         if not name:   
  13.             name = 'world'  
  14.         for c in xrange(int(i.times)):   
  15.             print 'Hello,', name+'!'  
  16.         return 'Hello, ' + name + '!'  
  17.   
  18. if __name__ == "__main__":  
  19.     app.run()  
实际上web 应用的代码就只得上面的几行,而且这是一个完整的web.py 应用。

3.启动服务

在你的命令行下输入:
[python] view plain copy
  1. $ python code.py                               # 使用默认端口 8080  
  2. 或者  
  3. $ python code.py 10000                         # 改变端口为 10000  
你的web.py 应用已经启动了服务器。通过浏览器访问:http://localhost:8080/ ,会见到”Hello, world!“。

修改默认端口
在启动服务器的时候,如果你不想使用默认端口,你可以使用这样的命令来指定端口号: python code.py 8888。

4. 调试

直接添加一行 web.internalerror = web.debugerror 即可。如下
[python] view plain copy
  1. if __name__=="__main__":  
  2.     web.internalerror = web.debugerror  
  3.     app.run()  


5. 模板

更多关于 web.py templates 可以访问    http://webpy.org/docs/0.3/templetor.zh-cn
在Python 里面编写HTML 代码是相当累赘的,而在HTML 里嵌入Python 代码则有趣得多。幸运地,web.py 使这过程变得相当容易。
注意:旧版本的web.py 是用Cheetah templates 模板的,你可以继续使用,但官方已不再提供支持。
新建一个 code.py 的 python文件。内容如下:
[python] view plain copy
  1. import web  
  2.   
  3.   
  4. urls = (  
  5.     # '/(.*)', 'hello',  
  6.     '/hello_1[/]?.*''hello_1',  
  7.     '/hello_2/(.*)''hello_2',  
  8. )  
  9.   
  10. app = web.application(urls, globals())  
  11. render=web.template.render('templates')  
  12.   
  13. class hello_1:  
  14.   
  15.     def GET(self):          
  16.         return render.index_1()   
  17.   
  18.   
  19. class hello_2:  
  20.   
  21.     def GET(self, name):          
  22.         return render.index_2("Lisa")   
  23.           
  24. if __name__ == "__main__":  
  25.     app.run()  

创建模板
这里,我们先在项目 code.py 同一级目录中新建一个目录(例如 templates )集中存放并用来组织模板文件,便于管理。然后在templates下新建HTML 文件(例如:”index.html“)。这里新建 两个 HTML 文件。 index_1.html 和 index_2.html
index_1.html 文件内容如下:
[html] view plain copy
  1. <em>Hello</em>, world!  
这是一个最简单的html页面代码。
index_2.html 文件内容如下:
[html] view plain copy
  1. $def with (name)  
  2.   
  3. <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">  
  4. <html xmlns="http://www.w3.org/1999/xhtml">  
  5. <head>  
  6.     <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />  
  7.     <title>Template</title>  
  8. </head>  
  9. <body>  
  10.     Hi, $name  
  11. </body>  
  12. </html>  
注意上面代码的缩进!
正如你所见的,上面的模板看上去跟这Python 文件很相似,以def with 语句开始,但在关键字前需要添加”$“。
注意:在模板内的变量,如果包含有HTML 标记,以$ 方式引用变量的话,HTML 标记只会以纯文本的显示出来。要想HTML 标记产生效果,可以用$: 引用变量。

使用模板
现在,回到 code.py 文件,在”import web” 的下一行添加:
[python] view plain copy
  1. render = web.template.render('templates/')  
这告诉web.py 在哪里可以搜索得到模板目录。提示:可在render 调用里添加cache = False 使得每次访问页面时都重载模板。
然后再修改使用这个模板的类,在这里  修改 类 hello_1 和 类 hello_2
[python] view plain copy
  1. class hello_1:  
  2.   
  3.     def GET(self):  
  4.         return render.index_1()   
  5.   
  6.   
  7. class hello_2:  
  8.   
  9.     def GET(self, name):  
  10.         # name = "Lisa"  
  11.         return render.index_2("Lisa")   
上面的 ”index_1“ 和 “index_2” 是模板的名字,”Lisa“ 是传递过去的参数。
同时修改urls为:
[python] view plain copy
  1. urls = (  
  2.     # '/(.*)', 'hello',  
  3.     '/hello_1[/]?.*''hello_1',  
  4.     '/hello_2/(.*)''hello_2',  
  5. )  
上面的“/(.*)” 是一个正则表达式。括号里面是要传递的参数。再将GET 方法修改如下:

[python] view plain copy
  1. def GET(self,name):  
  2.     print render.index_2(name)  
hello_1 页面调用 hello_1 类,使用 index_1.html 模板。打开 http://localhost:8080/hello_1 ,页面就会打印出 Hello, world 的字样。
hello_2/ 页面调用 hello_2 类,使用 index_2.html 模板,打开 http://localhost:8080/hello_2/,页面就会打印出 Hello, Lisa 的字样。

除此之外还有两种使用模板的方法
  1. 使用frender直接指定模板文件。GET函数最后两行改为
    [python] view plain copy
    1. render=web.template.frender("templates/index.html")  
    2. return render("Lisa")  
  2. 直接在代码里写出模板文件。GET最后两行改为
    [python] view plain copy
    1. template = "$def with (name)\nHello $name"  
    2. render = web.template.Template(template)  
    3. return render("Lisa")  

模板含义
现在解释一下这个 index.html 模板的含义:
[html] view plain copy
  1. $def with (name)  
  2.   
  3. <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">  
  4. <html xmlns="http://www.w3.org/1999/xhtml">  
  5. <head>  
  6.     <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />  
  7.     <title>Template</title>  
  8. </head>  
  9. <body>  
  10.     Hi, $name  
  11. </body>  
  12. </html>  
在index.html第一行 $def with (name)表示本模板接受一个名为name的参数,也就是对应index类中return render.index(“Lisa”)中的Lisa。
而render=web.template.render(“templates”)表示创建一个模板对象,模板是存放于templates目录下,然后就可以用所创建的 render 对象来访问相应的模板
比如templates目录下的index.html就是用render.index来表示(实际上是匹配寻找index.*文件,第一个匹配的就认为是所对应的模板文件),如果templates下还有个a目录,a目录下有个pagea.html,那么访问这个pagea模板就要用render.a.pagea的形式了。

页面参数
页面接收的参数可以多于一个,也可以没有,如果不需要参数,则就不需要$def with (name)这样的代码,删除掉这一句,同时修改模板中对name变量的引用,修改index类最后一句为return render.index()就可以了。

如果有参数,那么模板的第一行代码就必须是这个 $def with (…),可以多于一个参数,比如是这样$def with (gname, fname)。
模板下面的那行字改为Hi, $gname $fname。
同时Index类GET返回的时候赋予对应两个参数return render.index(“Lisa”,”Hayes”)。
这样,页面最后显示的是打印出Hi, Lisa Hayes的字样。
另外,模板接受的这个参数也可以是一个元组,比如像下面这样:return render.index((“Lisa”,”Hayes”))
在模板中可以如下以元组方式访问参数数据:Hi, $name[0] $name[1]

模板语法
模板语法与python语法基本一致,主要差别可以从上面的代码中看到,要使用到$符号表明这不是文本而是模板代码。也就是每当用到程序代码、对象的时候就必须用$来与html代码和页面显示文本相区别。

对象赋值
向对象赋值时需要在$与对象名之间留空格,如为一个名为vara的字符串对象赋值apple的代码为$ vara = “apple”。
另外,对象赋值语句必须独占一行,前面或后面有其他代码则会程序出错。

对象引用
引用对象的时候直接使用 $+对象名的形式,如$vara。
另外引用对象时还可以用{}或()将对象进行明确的分组,如$(vara)s就会表示apples,如果没有括号,程序则会把 $varas作为一个整体,也就变成对varas对象的引用而发生错误。另如果像如下定义两个数字型对象:
[plain] view plain copy
  1. $varb = 1  
  2. $varc = 2  
然后希望计算两个值的和,如果用$varb+$varc的形式,页面上只会得到1+2而不是3,这时也就需要把两个对象放在括号里,如$(varb+varc)的形式才能得到正确答案3。

注释
模板中支持单行注释,以$#符号开始到行末都是注释内容。
$#This is comment
注释前面可以有其他内容,但是不可以有赋值代码。
如下代码是正确的:Hi $#This is comment
但下面的则会出错:$ vara = “apple” $#This is comment

打印$符号
由于$符号在模板中有特殊用途,所以在页面上输出$时需要进行转义操作,用连续两个$表示在页面上输出一个$符号。
Can you lend me $50?

控制代码(循环、条件判断)
模板中支持for、while、if、elif、else,用法与在python一致,只是控制代码行要以$开始(包括break和continue命令),$开始的代码行中对象不需要在前面再加$符号,同时要注意缩进规则,如:
for 循环:
[html] view plain copy
  1. $def with (toUser,fromUser,createTime,articleCnt,articles)  
  2. <xml>  
  3.     <ToUserName><![CDATA[$toUser]]></ToUserName>  
  4.     <FromUserName><![CDATA[$fromUser]]></FromUserName>  
  5.     <CreateTime>$createTime</CreateTime>  
  6.     <MsgType><![CDATA[news]]></MsgType>  
  7.     <ArticleCount>$articleCnt</ArticleCount>  
  8.     <Articles>  
  9.         $for a in articles:  
  10.             <item>  
  11.                 <Title><![CDATA[$a['title']]]></Title>  
  12.                 <Description><![CDATA[$a['desc']]]></Description>  
  13.                 <PicUrl><![CDATA[$a['picUrl']]]></PicUrl>  
  14.                 <Url><![CDATA[$a['url']]]></Url>  
  15.             </item>  
  16.     </Articles>  
  17. </xml>  
if else判断:
[html] view plain copy
  1. $if times > max:  
  2.     Stop! In the name of love.  
  3. $else:  
  4.     Keep on, you can do it.  
在for循环中,有一组内置的变量可以使用,非常方便,分别如下所示:
  • loop.index: 循环次数计数 (1-开始)
  • loop.index0: 循环次数计数(0-开始)
  • loop.first: 如果是第一次循环则为True
  • loop.last: 如果是最后一次循环则为True
  • loop.odd: 如果是第奇数次循环则为True
  • loop.even: 如果是第偶数次循环则为True
  • loop.parity: 如果循环次数为奇数值为“odd” ,反之为 “even”
  • loop.parent: 本循环的外层循环对象
[html] view plain copy
  1. $for a in ["a", "b", "c", "d"]:   
  2.     $loop.index,$loop.index0,$loop.first,$loop.last,$loop.odd,$loop.even,$loop.parity<br/>  
将在页面上打印出:
[plain] view plain copy
  1. 1,0,True,False,True,False,odd  
  2. 2,1,False,False,False,True,even  
  3. 3,2,False,False,True,False,odd  
  4. 4,3,False,True,False,True,even  

函数-$def
函数定义也是与在python中类似,用def,只是也要在前面加$,代码也要注意$的使用和缩进:
[html] view plain copy
  1. $def hello(name=""):  
  2. Hello $name!  
函数调用也是用$加函数名的形式:
[html] view plain copy
  1. $hello("Lisa")  
当然,定义函数时也可以与html代码混编:
[html] view plain copy
  1. $def hello(name=""):  
  2. <strong/>Hello $name!</strong>  
但是调用的时候需要在函数名前用$:前缀,否则html代码将以plain text形式打印到页面上。
[html] view plain copy
  1. $:hello("Lisa")  


输出程序代码-$code块
如果想在模板里输入写一段python代码而又不想被$所烦恼,那么可以用到$code块。
页面上输出一段代码而不希望被系统理解为模板程序代码,就需要用到$code命令,比如在模板文件中写入下面一段:
[html] view plain copy
  1. $code:  
  2.     x=10  
  3.     def print_num(num):  
  4.     return "num is %d" % num  
然后再加上下面代码:
[html] view plain copy
  1. $print_num(x)  
  2. <br/>  
  3. $x  
这里就用在$code块中定义的print_num函数以x变量为参数在页面上输出一行:num is 10
然后下一行直接引用x变量,直接在页面上输出数字10。

$var
$var命令可以在模板中定义变量,在其他地方引用此模板对象的时候可以访问此定义的变量。
比如我们可以在index.html中添加如下一行:$var vara: this is vara
表示定义了一个名为vara的变量,变量值是字符串this is vara。
把index的GET函数改为:
[python] view plain copy
  1. def GET(self):  
  2.     render=web.template.render("templates")  
  3.     return render.index("Lisa""Hayes").vara  
那么结果显示在页面上的就是this is vara这句话。要注意一点的是,这种变量是字符串,即便如下定义变量:$var vara: 0
Vara也并不是数字0,如果把GET函数最后改成:return render.index(“Lisa”, “Hayes”).vara+1
会导致程序出错。如果希望得到期望中的结果1,则需要如下形式代码:return int(render.index(“Lisa”, “Hayes”).vara)+1

builtins and globals
在模板中,用户可以直接使用python的内建函数和变量,写函数变量包括range, min, max 以及 True 和 False等。 除此之外,如果希望在模板中使用其他的非内建功能,就需要一点特殊操作。要在创建render的时候显式指定所需要的功能函数。
[python] view plain copy
  1. import web  
  2. import markdown  
  3.   
  4. globals = {'markdown': markdown.markdown}  
  5. render =web.template.render('templates', globals=globals)  
这样,在模板中就可以用$markdown来引用markdown.markdown了。同样,也可以用这种办法来禁用builtins
[python] view plain copy
  1. # disable all builtins  
  2. render = web.template.render('templates', builtins={})  

模板复用
当多个页面有着相同的结构框架的时候,为每一个页面单独维护一个模板就显得比较麻烦,web.py提供了一种简易的解决方法。
这时候就要用到创建render时使用base参数:
[html] view plain copy
  1. render=web.template.render("templates",base="layout")  
  2. return render.index("Lisa", "Hayes")  
这个layout表示要以templates下的layout.html模板为通用模板框架。因此我们还要在templates目录下新建一个layout.html文件,写下如下代码:
[html] view plain copy
  1. $def with (content)  
  2.     <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">  
  3.     <html xmlns="http://www.w3.org/1999/xhtml">  
  4.     <head>  
  5.         <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />  
  6.         <title>Layout</title>  
  7.     </head>  
  8.     <body>  
  9.         $:content  
  10.     </body>  
  11. </html>  
可以看到,这个模板文件必须是有一个参数content。然后修改index.html,只保留如下代码,其他删掉:
[html] view plain copy
  1. $def with(gname, fname)  
  2.     Hi, $(gname) $(fname)  
运行程序,页面上打印Hi, Lisa Hayes,查看代码会发现最终代码就是index.html和layout.html合并在一起的结果,index.html中的内容被嵌入到layout.html中的$:content处。
在layout.html模板中还可以引用index.html中定义的var变量,这为程序带来了更多的灵活性,比如我们希望在不同的页面在使用同一个layout模板的时候能有不同的title,可以在使用layout的模板中定义如下一个var变量:$var title:This is index.html
然后在layout.html中的title处修改为:<title>$content.title</title>
这样,访问index.html时显示在浏览器上的title就是This is index.html,而不是原来的Layout了。

在模板中使用python代码模块
在默认状态下,在模板中是不能直接调用其他python代码模块文件中的程序的,必须做一些额外的操作。
首先,我们新建一个模块,叫module1.py,在里面写一个函数:
[python] view plain copy
  1. def hello_from_m1(name=""):  
  2.     return "hello %s, this is module1" % name  
在main.py里导入module1:import module1
并且修改GET函数中创建render的代码为:
[python] view plain copy
  1. def GET(self):  
  2.     render=web.template.render("templates",base="layout",globals={"m1":module1})  
  3.     return render.index("Lisa")  
globals参数中传递的是一个字典,key以字符串表示模块在模板中使用时的名称,value部分就是这个要在模块中使用的模块或对象的真实名称了。
最后在要使用此模块的模板中就可以用$m1来引用此模块了。比如在index.html中添加下面一行代码:$m1.hello_from_m1(gname)
就会调用module1中的hello_from_m1函数,在页面上打印出:hello Lisa, this is module1

在web.py模板中使用jQuery
在jQuery中$也是一个关键字,这样的话如果在模板中使用jQuery就会冲突,这时候只需要用$做一下转义就可以了,比如:
[html] view plain copy
  1. <script type="text/javascript">  
  2. $(document).ready(function()  
  3. {  
  4.     alert("It works.");  
  5. });  
  6. </script>  

6. 数据库


Web.py 更多关于数据库的操作:http://webpy.org/cookbook/index.zh-cn
注意:在你开始连接数据库之前,请先安装正确的数据库驱动。比如 MySQLdb、psycopg2。如果需要尝试连接 池(database pool)功能,还得装下DBUtils。这几个模块都可以通过easy_install 或者 pip 来安装。
连接数据库:

[python] view plain copy
  1. import web  
  2. db = web.database(dbn='postgres', db='mydata', user='dbuser', pw='')  
操作 数据库 示例
[plain] view plain copy
  1. select 查询  
  2. # 查询表  
  3. entries = db.select('mytable')       
  4. # where 条件  
  5. myvar = dict(name="Bob")  
  6. results = db.select('mytable', myvar, where="name = $name")  
  7. results = db.select('mytable', where="id>100")  
  8. # 查询具体列  
  9. results = db.select('mytable', what="id,name")  
  10. # order by  
  11. results = db.select('mytable', order="post_date DESC")  
  12. # group  
  13. results = db.select('mytable', group="color")  
  14. # limit  
  15. results = db.select('mytable', limit=10)  
  16. # offset  
  17. results = db.select('mytable', offset=10)  
  18.   
  19.   
  20. 更新  
  21. db.update('mytable', where="id = 10", value1 = "foo")  
  22.   
  23.   
  24. 删除  
  25. db.delete('mytable', where="id=10")  
  26.   
  27.   
  28. 复杂查询  
  29. # count  
  30. results = db.query("SELECT COUNT(*) AS total_users FROM users")  
  31. print results[0].total_users  
  32. # join  
  33. results = db.query("SELECT * FROM entries JOIN users WHERE entries.author_id = users.id")  
  34. # 防止SQL注入可以这么干  
  35. results = db.query("SELECT * FROM users WHERE id=$id", vars={'id':10})  
  36.   
  37.   
  38. 多数据库操作 (web.py大于0.3)  
  39. db1 = web.database(dbn='mysql', db='dbname1', user='foo')  
  40. db2 = web.database(dbn='mysql', db='dbname2', user='foo')  
  41. print db1.select('foo', where='id=1')  
  42. print db2.select('bar', where='id=5')  
  43.   
  44.   
  45. 事务  
  46. t = db.transaction()  
  47. try:  
  48.     db.insert('person', name='foo')  
  49.     db.insert('person', name='bar')  
  50. except:  
  51.     t.rollback()  
  52.     raise  
  53. else:  
  54.     t.commit()  
  55.   
  56. # Python 2.5+ 可以用with  
  57. from __future__ import with_statement  
  58. with db.transaction():  
  59.     db.insert('person', name='foo')  
  60.     db.insert('person', name='bar')  
现在,在数据库里创建一个简单的表:
  1. CREATE TABLE todo (  
  2.   id serial primary key,  
  3.   title text,  
  4.   created timestamp default now(),  
  5.   done boolean default 'f'  
  6. );  
  7.   
  8.   
  9. /* 初始化一行 */  
  10. INSERT INTO todo (title) VALUES ('Learn web.py');  
回到 code.py,修改GET 方法如下:
[python] view plain copy
  1. def GET(self):  
  2.     todos = db.select('todo')  
  3.     print render.index(todos)  
修改urls 变量:
[python] view plain copy
  1. urls = (  
  2.     '/''index')  
重新编辑index.html 文件如下:
[plain] view plain copy
  1. $def with (todos)  
  2. <ul>  
  3. $for todo in todos:  
  4.     <li id="t$todo.id">$todo.title</li>  
  5. </ul>  
现在,可以访问”/“,如果显示”Learn web.py“,则祝贺你成功了!
现在,再让我们看看如何向数据库写入。在index.html 文件的尾部添加如下内容:
[html] view plain copy
  1. <form method="post" action="add">  
  2.    <p>  
  3.        <input type="text" name="title" />  
  4.        <input type="submit" value="Add" />  
  5.    </p>  
  6. </form>  
修改code.py 文件的urls 变量如下:
[python] view plain copy
  1. urls = (  
  2.     '/''index',  
  3.     '/add''add'  
  4. )  
在code.py 里添加一个类:
[python] view plain copy
  1. class add:  
  2.     def POST(self):  
  3.         i = web.input()  
  4.         n = db.insert('todo', title=i.title)  
  5.         web.seeother('/')  
web.input 使你能够方便地访问用户通过表单提交上来的变量。db.insert 用于向数据库的 “todo” 表插入数据,并且返回新插入行的ID。web.seeother 用于重转向到”/“。
提示:对于数据库的操作,还有db.transact(), db.commit(), db.rollback()db.update()
在web.py 里,还有web.inputweb.query 和其它的函数,返回”Storage objects”,可以像字典型类(dictionaries) 的使用。

使用 Web.py 搭建一个测试网站案例


Web.py Form库文档 和 示例代码 :http://webpy.org/form
参考 http://blog.csdn.net/freeking101/article/details/76148434  这篇文章改写成 Web.py 搭建测试网站

先看 官网一个使用 Form 表单的示例(code.py):

[python] view plain copy
  1. import web  
  2. from web import form  
  3.   
  4. render = web.template.render('templates/')  
  5.   
  6. urls = ('/''index')  
  7. app = web.application(urls, globals())  
  8.   
  9. myform = form.Form(   
  10.     form.Textbox("boe"),   
  11.     form.Textbox("bax",   
  12.         form.notnull,  
  13.         form.regexp('\d+''Must be a digit'),  
  14.         form.Validator('Must be more than 5'lambda x:int(x)>5)),  
  15.     form.Textarea('moe'),  
  16.     form.Checkbox('curly'),   
  17.     form.Dropdown('french', ['mustard''fries''wine']))   
  18.   
  19. class index:   
  20.     def GET(self):   
  21.         form = myform()  
  22.         # make sure you create a copy of the form by calling it (line above)  
  23.         # Otherwise changes will appear globally  
  24.         print(form.render())  
  25.         return render.formtest(form)  
  26.   
  27.     def POST(self):   
  28.         form = myform()   
  29.         if not form.validates():   
  30.             print(form.render())  
  31.             return render.formtest(form)  
  32.         else:  
  33.             # form.d.boe and form['boe'].value are equivalent ways of  
  34.             # extracting the validated arguments from the form.  
  35.             return "Grrreat success! boe: %s, bax: %s" % (form.d.boe, form['bax'].value)  
  36.   
  37. if __name__=="__main__":  
  38.     web.internalerror = web.debugerror  
  39.     app.run()  

formtest.html 代码如下:

[html] view plain copy
  1. $def with (form)  
  2.   
  3. <div align="center">  
  4. <form name="main" method="post">   
  5. $if not form.valid: <p class="error">Try again, AmeriCAN:</p>  
  6. $:form.render()  
  7. <input type="submit" />  
  8. </form>  
  9. <div>  

Linux 下运行结果


然后根据上面内容开始改写 自己的网站

2 条评论:

  1. Do you need to increase your credit score?
    Do you intend to upgrade your school grade?
    Do you want to hack your cheating spouse Email, whatsapp, Facebook, instagram or any social network?
    Do you need any information concerning any database.
    Do you need to retrieve deleted files?
    Do you need to clear your criminal records or DMV?
    Do you want to remove any site or link from any blog?
    you should contact this hacker, he is reliable and good at the hack jobs..
    contact : cybergoldenhacker at gmail dot com

    回复删除
  2. I can’t say much but with my experience through divorce, I had no one until I met hackingsetting50@gmail.com online then I contacted him, surprisingly he helped me hack into my partner's phone and all his social media platforms and i can now access everything and even documented and printed stuffs to show as evidence , now I’m happy with my kids and working for Riches. I hope this helps anyone in need.

    Thanks.

    回复删除

注意:只有此博客的成员才能发布评论。

Also Read: