简单而直接的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
print ?
  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()  
import web

urls = (
    '/(.*)', 'hello'
)

app = web.application(urls, globals())

class hello:
    def GET(self, name):
        i = web.input(times=1)
        if not name: 
            name = 'world'
        for c in xrange(int(i.times)): 
            print 'Hello,', name+'!'
        return 'Hello, ' + name + '!'

if __name__ == "__main__":
    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
print ?
  1. import web  
import web

现在,我们须要告诉web.py URL 如何组织,让我们以一个简单例子开始:

[python] view plain copy
print ?
  1. urls = (  
  2.   ’/’‘index’    )  
urls = (
  '/', 'index'    )

在上面的例子中,第一部分是匹配URL的正则表达式,像//help/faq/item/(\d+)等(\d+将匹配数字)。圆括号表示捕捉对应的数据以便后面使用。第二部分是接受请求的类名称,像indexviewwelcomes.hello(welcomes模块的hello类),或者get_\1\1 会被正则表达式捕捉到的内容替换,剩下来捕捉的的内容将被传递到你的函数中去。(‘index’)是一个类名,匹配的请求将会被发送过去。这行表示我们要URL/(首页)被一个叫index的类处理。

现在我们需要创建一个列举这些 url 的 application。

[python] view plain copy
print ?
  1. app = web.application(urls, globals())  
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
print ?
  1. class index:  
  2.     def GET(self):  
  3.         print “Hello, world!”  
class index:
    def GET(self):
        print "Hello, world!"

当接收到一个GET 请求时,上面的GET 方法将会被web.py 调用。好的。现在,我们只需添加最后一行代码,让web.py 启动网页应用:

[python] view plain copy
print ?
  1. if __name__ == “__main__”:  
  2.     app.run()  
if __name__ == "__main__":
    app.run()

上面告诉web.py 如何配置URLs,以及找寻的类在文件中的全局命名空间。然后为我们启动上面的应用。

整个 code.py 文件的内容如下:

[python] view plain copy
print ?
  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()  
import web

urls = (
    '/(.*)', 'hello'
)

app = web.application(urls, globals())

class hello:
    def GET(self, name):
        i = web.input(times=1)
        if not name: 
            name = 'world'
        for c in xrange(int(i.times)): 
            print 'Hello,', name+'!'
        return 'Hello, ' + name + '!'

if __name__ == "__main__":
    app.run()

实际上web 应用的代码就只得上面的几行,而且这是一个完整的web.py 应用。


3.启动服务

在你的命令行下输入:

[python] view plain copy
print ?
  1. &nbsp;python&nbsp;code.py&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="comment">#&nbsp;使用默认端口&nbsp;8080</span><span>&nbsp;&nbsp;</span></span></li><li class=""><span>或者&nbsp;&nbsp;</span></li><li class="alt"><span> &nbsp;python&nbsp;code.py&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="comment">#&nbsp;使用默认端口&nbsp;8080</span><span>&nbsp;&nbsp;</span></span></li><li class=""><span>或者&nbsp;&nbsp;</span></li><li class="alt"><span>  python code.py 10000                         # 改变端口为 10000  
$ python code.py                               # 使用默认端口 8080
或者
$ 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
print ?
  1. if __name__==“__main__”:  
  2.     web.internalerror = web.debugerror  
  3.     app.run()  
if __name__=="__main__":
    web.internalerror = web.debugerror
    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
print ?
  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()  
import web


urls = (
    # '/(.*)', 'hello',
    '/hello_1[/]?.*', 'hello_1',
    '/hello_2/(.*)', 'hello_2',
)

app = web.application(urls, globals())
render=web.template.render('templates')

class hello_1:

    def GET(self):        
        return render.index_1() 


class hello_2:

    def GET(self, name):        
        return render.index_2("Lisa") 

if __name__ == "__main__":
    app.run()


创建模板

这里,我们先在项目 code.py 同一级目录中新建一个目录(例如 templates )集中存放并用来组织模板文件,便于管理。然后在templates下新建HTML 文件(例如:”index.html“)。这里新建 两个 HTML 文件。 index_1.html 和 index_2.html


index_1.html 文件内容如下:

  1. <em>Hello</em>, world!  
<em>Hello</em>, world!

这是一个最简单的html页面代码。

index_2.html 文件内容如下:

  1. def&nbsp;with&nbsp;(name)&nbsp;&nbsp;</span></span></li><li class=""><span>&nbsp;&nbsp;</span></li><li class="alt"><span>&lt;!DOCTYPE&nbsp;html&nbsp;PUBLIC&nbsp;"-//W3C//DTD&nbsp;XHTML&nbsp;1.0&nbsp;Strict//EN"&nbsp;"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"<span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></span></li><li class=""><span><span class="tag">&lt;</span><span class="tag-name">html</span><span>&nbsp;</span><span class="attribute">xmlns</span><span>=</span><span class="attribute-value">"http://www.w3.org/1999/xhtml"</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></span></li><li class="alt"><span><span class="tag">&lt;</span><span class="tag-name">head</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></span></li><li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;<span class="tag">&lt;</span><span class="tag-name">meta</span><span>&nbsp;</span><span class="attribute">http-equiv</span><span>=</span><span class="attribute-value">"Content-Type"</span><span>&nbsp;</span><span class="attribute">content</span><span>=</span><span class="attribute-value">"text/html;&nbsp;charset=utf-8"</span><span>&nbsp;</span><span class="tag">/&gt;</span><span>&nbsp;&nbsp;</span></span></li><li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;<span class="tag">&lt;</span><span class="tag-name">title</span><span class="tag">&gt;</span><span>Template</span><span class="tag">&lt;/</span><span class="tag-name">title</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></span></li><li class=""><span><span class="tag">&lt;/</span><span class="tag-name">head</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></span></li><li class="alt"><span><span class="tag">&lt;</span><span class="tag-name">body</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></span></li><li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;Hi,&nbsp; def&nbsp;with&nbsp;(name)&nbsp;&nbsp;</span></span></li><li class=""><span>&nbsp;&nbsp;</span></li><li class="alt"><span>&lt;!DOCTYPE&nbsp;html&nbsp;PUBLIC&nbsp;"-//W3C//DTD&nbsp;XHTML&nbsp;1.0&nbsp;Strict//EN"&nbsp;"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"<span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></span></li><li class=""><span><span class="tag">&lt;</span><span class="tag-name">html</span><span>&nbsp;</span><span class="attribute">xmlns</span><span>=</span><span class="attribute-value">"http://www.w3.org/1999/xhtml"</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></span></li><li class="alt"><span><span class="tag">&lt;</span><span class="tag-name">head</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></span></li><li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;<span class="tag">&lt;</span><span class="tag-name">meta</span><span>&nbsp;</span><span class="attribute">http-equiv</span><span>=</span><span class="attribute-value">"Content-Type"</span><span>&nbsp;</span><span class="attribute">content</span><span>=</span><span class="attribute-value">"text/html;&nbsp;charset=utf-8"</span><span>&nbsp;</span><span class="tag">/&gt;</span><span>&nbsp;&nbsp;</span></span></li><li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;<span class="tag">&lt;</span><span class="tag-name">title</span><span class="tag">&gt;</span><span>Template</span><span class="tag">&lt;/</span><span class="tag-name">title</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></span></li><li class=""><span><span class="tag">&lt;/</span><span class="tag-name">head</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></span></li><li class="alt"><span><span class="tag">&lt;</span><span class="tag-name">body</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></span></li><li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;Hi,&nbsp; name  
  2. </body>  
  3. </html>  
$def with (name)

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <title>Template</title>
</head>
<body>
    Hi, $name
</body>
</html>

注意上面代码的缩进!

正如你所见的,上面的模板看上去跟这Python 文件很相似,以def with 语句开始,但在关键字前需要添加”$“。

注意:在模板内的变量,如果包含有HTML 标记,以$ 方式引用变量的话,HTML 标记只会以纯文本的显示出来。要想HTML 标记产生效果,可以用$: 引用变量。


使用模板

现在,回到 code.py 文件,在”import web” 的下一行添加:

[python] view plain copy
print ?
  1. render = web.template.render(‘templates/’)  
render = web.template.render('templates/')

这告诉web.py 在哪里可以搜索得到模板目录。提示:可在render 调用里添加cache = False 使得每次访问页面时都重载模板。

然后再修改使用这个模板的类,在这里  修改 类 hello_1 和 类 hello_2

[python] view plain copy
print ?
  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”)   
class hello_1:

    def GET(self):
        return render.index_1() 


class hello_2:

    def GET(self, name):
        # name = "Lisa"
        return render.index_2("Lisa") 

上面的 ”index_1“ 和 “index_2” 是模板的名字,”Lisa“ 是传递过去的参数。

同时修改urls为:

[python] view plain copy
print ?
  1. urls = (  
  2.     # ’/(.*)’, ‘hello’,  
  3.     ’/hello_1[/]?.*’‘hello_1’,  
  4.     ’/hello_2/(.*)’‘hello_2’,  
  5. )  
urls = (
    # '/(.*)', 'hello',
    '/hello_1[/]?.*', 'hello_1',
    '/hello_2/(.*)', 'hello_2',
)

上面的“/(.*)” 是一个正则表达式。括号里面是要传递的参数。再将GET 方法修改如下:

[python] view plain copy
print ?
  1. def GET(self,name):  
  2.     print render.index_2(name)  
def GET(self,name):
    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
    print ?
    1. render=web.template.frender(“templates/index.html”)  
    2. return render(“Lisa”)  
      render=web.template.frender("templates/index.html")
      return render("Lisa")
  2. 直接在代码里写出模板文件。GET最后两行改为
    [python] view plain copy
    print ?
    1. template = def&nbsp;with&nbsp;(name)\nHello&nbsp; def&nbsp;with&nbsp;(name)\nHello&nbsp; name”  
    2. render = web.template.Template(template)  
    3. return render(“Lisa”)  
      template = "$def with (name)\nHello $name"
      render = web.template.Template(template)
      return render("Lisa")


模板含义

现在解释一下这个 index.html 模板的含义:

  1. def&nbsp;with&nbsp;(name)&nbsp;&nbsp;</span></span></li><li class=""><span>&nbsp;&nbsp;</span></li><li class="alt"><span>&lt;!DOCTYPE&nbsp;html&nbsp;PUBLIC&nbsp;"-//W3C//DTD&nbsp;XHTML&nbsp;1.0&nbsp;Strict//EN"&nbsp;"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"<span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></span></li><li class=""><span><span class="tag">&lt;</span><span class="tag-name">html</span><span>&nbsp;</span><span class="attribute">xmlns</span><span>=</span><span class="attribute-value">"http://www.w3.org/1999/xhtml"</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></span></li><li class="alt"><span><span class="tag">&lt;</span><span class="tag-name">head</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></span></li><li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;<span class="tag">&lt;</span><span class="tag-name">meta</span><span>&nbsp;</span><span class="attribute">http-equiv</span><span>=</span><span class="attribute-value">"Content-Type"</span><span>&nbsp;</span><span class="attribute">content</span><span>=</span><span class="attribute-value">"text/html;&nbsp;charset=utf-8"</span><span>&nbsp;</span><span class="tag">/&gt;</span><span>&nbsp;&nbsp;</span></span></li><li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;<span class="tag">&lt;</span><span class="tag-name">title</span><span class="tag">&gt;</span><span>Template</span><span class="tag">&lt;/</span><span class="tag-name">title</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></span></li><li class=""><span><span class="tag">&lt;/</span><span class="tag-name">head</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></span></li><li class="alt"><span><span class="tag">&lt;</span><span class="tag-name">body</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></span></li><li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;Hi,&nbsp; def&nbsp;with&nbsp;(name)&nbsp;&nbsp;</span></span></li><li class=""><span>&nbsp;&nbsp;</span></li><li class="alt"><span>&lt;!DOCTYPE&nbsp;html&nbsp;PUBLIC&nbsp;"-//W3C//DTD&nbsp;XHTML&nbsp;1.0&nbsp;Strict//EN"&nbsp;"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"<span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></span></li><li class=""><span><span class="tag">&lt;</span><span class="tag-name">html</span><span>&nbsp;</span><span class="attribute">xmlns</span><span>=</span><span class="attribute-value">"http://www.w3.org/1999/xhtml"</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></span></li><li class="alt"><span><span class="tag">&lt;</span><span class="tag-name">head</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></span></li><li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;<span class="tag">&lt;</span><span class="tag-name">meta</span><span>&nbsp;</span><span class="attribute">http-equiv</span><span>=</span><span class="attribute-value">"Content-Type"</span><span>&nbsp;</span><span class="attribute">content</span><span>=</span><span class="attribute-value">"text/html;&nbsp;charset=utf-8"</span><span>&nbsp;</span><span class="tag">/&gt;</span><span>&nbsp;&nbsp;</span></span></li><li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;<span class="tag">&lt;</span><span class="tag-name">title</span><span class="tag">&gt;</span><span>Template</span><span class="tag">&lt;/</span><span class="tag-name">title</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></span></li><li class=""><span><span class="tag">&lt;/</span><span class="tag-name">head</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></span></li><li class="alt"><span><span class="tag">&lt;</span><span class="tag-name">body</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></span></li><li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;Hi,&nbsp; name  
  2. </body>  
  3. </html>  
$def with (name)

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <title>Template</title>
</head>
<body>
    Hi, $name
</body>
</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()就可以了。

如果有参数,那么模板的第一行代码就必须是这个 defwith() d e f w i t h ( … ) , 可 以 多 于 一 个 参 数 , 比 如 是 这 样 def with (gname, fname)。

模板下面的那行字改为Hi, gname g n a m e fname。

同时Index类GET返回的时候赋予对应两个参数return render.index(“Lisa”,”Hayes”)。

这样,页面最后显示的是打印出Hi, Lisa Hayes的字样。

另外,模板接受的这个参数也可以是一个元组,比如像下面这样:return render.index((“Lisa”,”Hayes”))

在模板中可以如下以元组方式访问参数数据:Hi, name[0] n a m e [ 0 ] name[1]


模板语法

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


对象赋值

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


对象引用

引用对象的时候直接使用 + + 对 象 名 的 形 式 , 如 vara。
另外引用对象时还可以用{}或()将对象进行明确的分组,如 (vara)sapples ( v a r a ) s 就 会 表 示 a p p l e s , 如 果 没 有 括 号 , 程 序 则 会 把 varas作为一个整体,也就变成对varas对象的引用而发生错误。另如果像如下定义两个数字型对象:

  1. varb&nbsp;=&nbsp;1&nbsp;&nbsp;</span></span></li><li class=""><span> varb&nbsp;=&nbsp;1&nbsp;&nbsp;</span></span></li><li class=""><span> varc = 2  
$varb = 1
$varc = 2

然后希望计算两个值的和,如果用 varb+ v a r b + varc的形式,页面上只会得到1+2而不是3,这时也就需要把两个对象放在括号里,如$(varb+varc)的形式才能得到正确答案3。


注释

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


打印$符号

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

Can you lend me $50?


控制代码(循环、条件判断)

模板中支持for、while、if、elif、else,用法与在python一致,只是控制代码行要以 breakcontinue 开 始 ( 包 括 b r e a k 和 c o n t i n u e 命 令 ) , 开始的代码行中对象不需要在前面再加$符号,同时要注意缩进规则,如:

for 循环:

  1. def&nbsp;with&nbsp;(toUser,fromUser,createTime,articleCnt,articles)&nbsp;&nbsp;</span></span></li><li class=""><span><span class="tag">&lt;</span><span class="tag-name">xml</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></span></li><li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;<span class="tag">&lt;</span><span class="tag-name">ToUserName</span><span class="tag">&gt;</span><span class="cdata">&lt;![CDATA[ def&nbsp;with&nbsp;(toUser,fromUser,createTime,articleCnt,articles)&nbsp;&nbsp;</span></span></li><li class=""><span><span class="tag">&lt;</span><span class="tag-name">xml</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></span></li><li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;<span class="tag">&lt;</span><span class="tag-name">ToUserName</span><span class="tag">&gt;</span><span class="cdata">&lt;![CDATA[ toUser]]></ToUserName>  
  2.     <FromUserName><![CDATA[fromUser]]&gt;</span><span class="tag">&lt;/</span><span class="tag-name">FromUserName</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></span></li><li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;<span class="tag">&lt;</span><span class="tag-name">CreateTime</span><span class="tag">&gt;</span><span> fromUser]]&gt;</span><span class="tag">&lt;/</span><span class="tag-name">FromUserName</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></span></li><li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;<span class="tag">&lt;</span><span class="tag-name">CreateTime</span><span class="tag">&gt;</span><span> createTime</CreateTime>  
  3.     <MsgType><![CDATA[news]]></MsgType>  
  4.     <ArticleCount>articleCnt</span><span class="tag">&lt;/</span><span class="tag-name">ArticleCount</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></span></li><li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;<span class="tag">&lt;</span><span class="tag-name">Articles</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></span></li><li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; articleCnt</span><span class="tag">&lt;/</span><span class="tag-name">ArticleCount</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></span></li><li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;<span class="tag">&lt;</span><span class="tag-name">Articles</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></span></li><li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for a in articles:  
  5.             <item>  
  6.                 <Title><![CDATA[a['title']]]&gt;</span><span class="tag">&lt;/</span><span class="tag-name">Title</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></span></li><li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="tag">&lt;</span><span class="tag-name">Description</span><span class="tag">&gt;</span><span class="cdata">&lt;![CDATA[ a['title']]]&gt;</span><span class="tag">&lt;/</span><span class="tag-name">Title</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></span></li><li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="tag">&lt;</span><span class="tag-name">Description</span><span class="tag">&gt;</span><span class="cdata">&lt;![CDATA[ a[‘desc’]]]></Description>  
  7.                 <PicUrl><![CDATA[a['picUrl']]]&gt;</span><span class="tag">&lt;/</span><span class="tag-name">PicUrl</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></span></li><li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="tag">&lt;</span><span class="tag-name">Url</span><span class="tag">&gt;</span><span class="cdata">&lt;![CDATA[ a['picUrl']]]&gt;</span><span class="tag">&lt;/</span><span class="tag-name">PicUrl</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></span></li><li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="tag">&lt;</span><span class="tag-name">Url</span><span class="tag">&gt;</span><span class="cdata">&lt;![CDATA[ a[‘url’]]]></Url>  
  8.             </item>  
  9.     </Articles>  
  10. </xml>  
$def with (toUser,fromUser,createTime,articleCnt,articles)
<xml>
    <ToUserName><![CDATA[$toUser]]></ToUserName>
    <FromUserName><![CDATA[$fromUser]]></FromUserName>
    <CreateTime>$createTime</CreateTime>
    <MsgType><![CDATA[news]]></MsgType>
    <ArticleCount>$articleCnt</ArticleCount>
    <Articles>
        $for a in articles:
            <item>
                <Title><![CDATA[$a['title']]]></Title>
                <Description><![CDATA[$a['desc']]]></Description>
                <PicUrl><![CDATA[$a['picUrl']]]></PicUrl>
                <Url><![CDATA[$a['url']]]></Url>
            </item>
    </Articles>
</xml>

if else判断:

  1. if&nbsp;times&nbsp;</span><span class="tag">&gt;</span><span>&nbsp;max:&nbsp;&nbsp;</span></span></li><li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;Stop!&nbsp;In&nbsp;the&nbsp;name&nbsp;of&nbsp;love.&nbsp;&nbsp;</span></li><li class="alt"><span> if&nbsp;times&nbsp;</span><span class="tag">&gt;</span><span>&nbsp;max:&nbsp;&nbsp;</span></span></li><li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;Stop!&nbsp;In&nbsp;the&nbsp;name&nbsp;of&nbsp;love.&nbsp;&nbsp;</span></li><li class="alt"><span> else:  
  2.     Keep on, you can do it.  
$if times > max:
    Stop! In the name of love.
$else:
    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: 本循环的外层循环对象
  1. for&nbsp;a&nbsp;in&nbsp;["a",&nbsp;"b",&nbsp;"c",&nbsp;"d"]:&nbsp;&nbsp;&nbsp;</span></span></li><li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp; for&nbsp;a&nbsp;in&nbsp;["a",&nbsp;"b",&nbsp;"c",&nbsp;"d"]:&nbsp;&nbsp;&nbsp;</span></span></li><li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp; loop.index, loop.index0, l o o p . i n d e x 0 , loop.first, loop.last, l o o p . l a s t , loop.odd, loop.even, l o o p . e v e n , loop.parity<br/>  
$for a in ["a", "b", "c", "d"]: 
    $loop.index,$loop.index0,$loop.first,$loop.last,$loop.odd,$loop.even,$loop.parity<br/>

将在页面上打印出:

  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  
1,0,True,False,True,False,odd
2,1,False,False,False,True,even
3,2,False,False,True,False,odd
4,3,False,True,False,True,even


函数-$def

函数定义也是与在python中类似,用def,只是也要在前面加 , 代 码 也 要 注 意 的使用和缩进:

  1. def&nbsp;hello(</span><span class="attribute">name</span><span>=</span><span class="attribute-value">""</span><span>):&nbsp;&nbsp;</span></span></li><li class=""><span>Hello&nbsp; def&nbsp;hello(</span><span class="attribute">name</span><span>=</span><span class="attribute-value">""</span><span>):&nbsp;&nbsp;</span></span></li><li class=""><span>Hello&nbsp; name!  
$def hello(name=""):
Hello $name!</pre>函数调用也是用$加函数名的形式:
    
    
  1. $hello("Lisa")&nbsp;&nbsp;</span></span></li></ol></div><pre class="html" name="code" style="display: none;">$hello("Lisa")
当然,定义函数时也可以与html代码混编:
  1. def&nbsp;hello(</span><span class="attribute">name</span><span>=</span><span class="attribute-value">""</span><span>):&nbsp;&nbsp;</span></span></li><li class=""><span><span class="tag">&lt;</span><span class="tag-name">strong</span><span class="tag">/&gt;</span><span>Hello&nbsp; def&nbsp;hello(</span><span class="attribute">name</span><span>=</span><span class="attribute-value">""</span><span>):&nbsp;&nbsp;</span></span></li><li class=""><span><span class="tag">&lt;</span><span class="tag-name">strong</span><span class="tag">/&gt;</span><span>Hello&nbsp; name!</strong>  
$def hello(name=""):
<strong/>Hello $name!&lt;/strong&gt;</pre>但是调用的时候需要在函数名前用$:前缀,否则html代码将以plain text形式打印到页面上。
    
    
  1. $:hello("Lisa")&nbsp;&nbsp;</span></span></li></ol></div><pre class="html" name="code" style="display: none;">$:hello("Lisa")


输出程序代码-$code块

如果想在模板里输入写一段python代码而又不想被 所 烦 恼 , 那 么 可 以 用 到 code块。

页面上输出一段代码而不希望被系统理解为模板程序代码,就需要用到$code命令,比如在模板文件中写入下面一段:

  1. code:&nbsp;&nbsp;</span></span></li><li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;<span class="attribute">x</span><span>=</span><span class="attribute-value">10</span><span>&nbsp;&nbsp;</span></span></li><li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;def&nbsp;print_num(num):&nbsp;&nbsp;</span></li><li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;"num&nbsp;is&nbsp;%d"&nbsp;%&nbsp;num&nbsp;&nbsp;</span></li></ol></div><pre class="html" name="code" style="display: none;"> code:&nbsp;&nbsp;</span></span></li><li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;<span class="attribute">x</span><span>=</span><span class="attribute-value">10</span><span>&nbsp;&nbsp;</span></span></li><li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;def&nbsp;print_num(num):&nbsp;&nbsp;</span></li><li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;"num&nbsp;is&nbsp;%d"&nbsp;%&nbsp;num&nbsp;&nbsp;</span></li></ol></div><pre class="html" name="code" style="display: none;"> code: x=10 def print_num(num): return “num is %d” % num

    然后再加上下面代码:

    1. print_num(x)&nbsp;&nbsp;</span></span></li><li class=""><span><span class="tag">&lt;</span><span class="tag-name">br</span><span class="tag">/&gt;</span><span>&nbsp;&nbsp;</span></span></li><li class="alt"><span> print_num(x)&nbsp;&nbsp;</span></span></li><li class=""><span><span class="tag">&lt;</span><span class="tag-name">br</span><span class="tag">/&gt;</span><span>&nbsp;&nbsp;</span></span></li><li class="alt"><span> x  
    $print_num(x)
    <br/>
    $x

    这里就用在$code块中定义的print_num函数以x变量为参数在页面上输出一行:num is 10

    然后下一行直接引用x变量,直接在页面上输出数字10。


    $var

    var访index.html v a r 命 令 可 以 在 模 板 中 定 义 变 量 , 在 其 他 地 方 引 用 此 模 板 对 象 的 时 候 可 以 访 问 此 定 义 的 变 量 。 比 如 我 们 可 以 在 i n d e x . h t m l 中 添 加 如 下 一 行 : var vara: this is vara
    表示定义了一个名为vara的变量,变量值是字符串this is vara。
    把index的GET函数改为:

    [python] view plain copy
    print ?
    1. def GET(self):  
    2.     render=web.template.render(”templates”)  
    3.     return render.index(“Lisa”“Hayes”).vara  
    def GET(self):
        render=web.template.render("templates")
        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
    print ?
    1. import web  
    2. import markdown  
    3.   
    4. globals = {’markdown’: markdown.markdown}  
    5. render =web.template.render(’templates’, globals=globals)  
    import web
    import markdown
    
    globals = {'markdown': markdown.markdown}
    render =web.template.render('templates', globals=globals)

    这样,在模板中就可以用$markdown来引用markdown.markdown了。同样,也可以用这种办法来禁用builtins

    [python] view plain copy
    print ?
    1. # disable all builtins  
    2. render = web.template.render(’templates’, builtins={})  
    # disable all builtins
    render = web.template.render('templates', builtins={})


    模板复用

    当多个页面有着相同的结构框架的时候,为每一个页面单独维护一个模板就显得比较麻烦,web.py提供了一种简易的解决方法。
    这时候就要用到创建render时使用base参数:

    1. render=web.template.render(“templates”,base=“layout”)  
    2. return render.index(“Lisa”, “Hayes”)  
    render=web.template.render("templates",base="layout")
    return render.index("Lisa", "Hayes")

    这个layout表示要以templates下的layout.html模板为通用模板框架。因此我们还要在templates目录下新建一个layout.html文件,写下如下代码:

    1. def&nbsp;with&nbsp;(content)&nbsp;&nbsp;</span></span></li><li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&lt;!DOCTYPE&nbsp;html&nbsp;PUBLIC&nbsp;"-//W3C//DTD&nbsp;XHTML&nbsp;1.0&nbsp;Strict//EN"&nbsp;"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"<span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></span></li><li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;<span class="tag">&lt;</span><span class="tag-name">html</span><span>&nbsp;</span><span class="attribute">xmlns</span><span>=</span><span class="attribute-value">"http://www.w3.org/1999/xhtml"</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></span></li><li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;<span class="tag">&lt;</span><span class="tag-name">head</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></span></li><li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="tag">&lt;</span><span class="tag-name">meta</span><span>&nbsp;</span><span class="attribute">http-equiv</span><span>=</span><span class="attribute-value">"Content-Type"</span><span>&nbsp;</span><span class="attribute">content</span><span>=</span><span class="attribute-value">"text/html;&nbsp;charset=utf-8"</span><span>&nbsp;</span><span class="tag">/&gt;</span><span>&nbsp;&nbsp;</span></span></li><li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="tag">&lt;</span><span class="tag-name">title</span><span class="tag">&gt;</span><span>Layout</span><span class="tag">&lt;/</span><span class="tag-name">title</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></span></li><li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;<span class="tag">&lt;/</span><span class="tag-name">head</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></span></li><li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;<span class="tag">&lt;</span><span class="tag-name">body</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></span></li><li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; def&nbsp;with&nbsp;(content)&nbsp;&nbsp;</span></span></li><li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&lt;!DOCTYPE&nbsp;html&nbsp;PUBLIC&nbsp;"-//W3C//DTD&nbsp;XHTML&nbsp;1.0&nbsp;Strict//EN"&nbsp;"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"<span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></span></li><li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;<span class="tag">&lt;</span><span class="tag-name">html</span><span>&nbsp;</span><span class="attribute">xmlns</span><span>=</span><span class="attribute-value">"http://www.w3.org/1999/xhtml"</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></span></li><li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;<span class="tag">&lt;</span><span class="tag-name">head</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></span></li><li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="tag">&lt;</span><span class="tag-name">meta</span><span>&nbsp;</span><span class="attribute">http-equiv</span><span>=</span><span class="attribute-value">"Content-Type"</span><span>&nbsp;</span><span class="attribute">content</span><span>=</span><span class="attribute-value">"text/html;&nbsp;charset=utf-8"</span><span>&nbsp;</span><span class="tag">/&gt;</span><span>&nbsp;&nbsp;</span></span></li><li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="tag">&lt;</span><span class="tag-name">title</span><span class="tag">&gt;</span><span>Layout</span><span class="tag">&lt;/</span><span class="tag-name">title</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></span></li><li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;<span class="tag">&lt;/</span><span class="tag-name">head</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></span></li><li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;<span class="tag">&lt;</span><span class="tag-name">body</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></span></li><li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; :content  
    2.     </body>  
    3. </html>  
    $def with (content)
        <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
        <html xmlns="http://www.w3.org/1999/xhtml">
        <head>
            <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
            <title>Layout</title>
        </head>
        <body>
            $:content
        </body>
    </html>
    可以看到,这个模板文件必须是有一个参数content。然后修改index.html,只保留如下代码,其他删掉:
    1. def&nbsp;with(gname,&nbsp;fname)&nbsp;&nbsp;</span></span></li><li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;Hi,&nbsp; def&nbsp;with(gname,&nbsp;fname)&nbsp;&nbsp;</span></span></li><li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;Hi,&nbsp; (gname) (fname)&nbsp;&nbsp;</span></li></ol></div><pre class="html" name="code" style="display: none;"> (fname)&nbsp;&nbsp;</span></li></ol></div><pre class="html" name="code" style="display: none;"> def with(gname, fname) Hi, (gname) ( g n a m e ) (fname)

      运行程序,页面上打印Hi, Lisa Hayes,查看代码会发现最终代码就是index.html和layout.html合并在一起的结果,index.html中的内容被嵌入到layout.html中的 :contentlayout.htmlindex.htmlvar使layouttitle使layoutvar : c o n t e n t 处 。 在 l a y o u t . h t m l 模 板 中 还 可 以 引 用 i n d e x . h t m l 中 定 义 的 v a r 变 量 , 这 为 程 序 带 来 了 更 多 的 灵 活 性 , 比 如 我 们 希 望 在 不 同 的 页 面 在 使 用 同 一 个 l a y o u t 模 板 的 时 候 能 有 不 同 的 t i t l e , 可 以 在 使 用 l a y o u t 的 模 板 中 定 义 如 下 一 个 v a r 变 量 : 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
      print ?
      1. def hello_from_m1(name=”“):  
      2.     return “hello %s, this is module1” % name  
      def hello_from_m1(name=""):
          return "hello %s, this is module1" % name

      在main.py里导入module1:import module1

      并且修改GET函数中创建render的代码为:

      [python] view plain copy
      print ?
      1. def GET(self):  
      2.     render=web.template.render(”templates”,base=“layout”,globals={“m1”:module1})  
      3.     return render.index(“Lisa”)  
      def GET(self):
          render=web.template.render("templates",base="layout",globals={"m1":module1})
          return render.index("Lisa")

      globals参数中传递的是一个字典,key以字符串表示模块在模板中使用时的名称,value部分就是这个要在模块中使用的模块或对象的真实名称了。
      最后在要使用此模块的模板中就可以用 m1index.html m 1 来 引 用 此 模 块 了 。 比 如 在 i n d e x . h t m l 中 添 加 下 面 一 行 代 码 : m1.hello_from_m1(gname)
      就会调用module1中的hello_from_m1函数,在页面上打印出:hello Lisa, this is module1


      在web.py模板中使用jQuery

      在jQuery中 使jQuery 也 是 一 个 关 键 字 , 这 样 的 话 如 果 在 模 板 中 使 用 j Q u e r y 就 会 冲 突 , 这 时 候 只 需 要 用 做一下转义就可以了,比如:

      1. <script type=“text/javascript”>  
      2. $(document).ready(function()  
      3. {  
      4.     alert(“It works.”);  
      5. });  
      6. </script>  
      <script type="text/javascript">
      $(document).ready(function()
      {
          alert("It works.");
      });
      </script>


      6. 数据库


      Web.py 更多关于数据库的操作:http://webpy.org/cookbook/index.zh-cn

      注意:在你开始连接数据库之前,请先安装正确的数据库驱动。比如 MySQLdb、psycopg2。如果需要尝试连接 池(database pool)功能,还得装下DBUtils。这几个模块都可以通过easy_install 或者 pip 来安装。

      连接数据库:

      [python] view plain copy
      print ?
      1. import web  
      2. db = web.database(dbn=’postgres’, db=‘mydata’, user=‘dbuser’, pw=)  
      import web
      db = web.database(dbn='postgres', db='mydata', user='dbuser', pw='')

      操作 数据库 示例

      1. select 查询  
      2. # 查询表  
      3. entries = db.select(‘mytable’)       
      4. # where 条件  
      5. myvar = dict(name=”Bob”)  
      6. results = db.select(‘mytable’, myvar, where=”name = name")&nbsp;&nbsp;</span></li><li class="alt"><span>results&nbsp;=&nbsp;db.select('mytable',&nbsp;where="id&gt;100")&nbsp;&nbsp;</span></li><li class=""><span>#&nbsp;查询具体列&nbsp;&nbsp;</span></li><li class="alt"><span>results&nbsp;=&nbsp;db.select('mytable',&nbsp;what="id,name")&nbsp;&nbsp;</span></li><li class=""><span>#&nbsp;order&nbsp;by&nbsp;&nbsp;</span></li><li class="alt"><span>results&nbsp;=&nbsp;db.select('mytable',&nbsp;order="post_date&nbsp;DESC")&nbsp;&nbsp;</span></li><li class=""><span>#&nbsp;group&nbsp;&nbsp;</span></li><li class="alt"><span>results&nbsp;=&nbsp;db.select('mytable',&nbsp;group="color")&nbsp;&nbsp;</span></li><li class=""><span>#&nbsp;limit&nbsp;&nbsp;</span></li><li class="alt"><span>results&nbsp;=&nbsp;db.select('mytable',&nbsp;limit=10)&nbsp;&nbsp;</span></li><li class=""><span>#&nbsp;offset&nbsp;&nbsp;</span></li><li class="alt"><span>results&nbsp;=&nbsp;db.select('mytable',&nbsp;offset=10)&nbsp;&nbsp;</span></li><li class=""><span>&nbsp;&nbsp;</span></li><li class="alt"><span>&nbsp;&nbsp;</span></li><li class=""><span>更新&nbsp;&nbsp;</span></li><li class="alt"><span>db.update('mytable',&nbsp;where="id&nbsp;=&nbsp;10",&nbsp;value1&nbsp;=&nbsp;"foo")&nbsp;&nbsp;</span></li><li class=""><span>&nbsp;&nbsp;</span></li><li class="alt"><span>&nbsp;&nbsp;</span></li><li class=""><span>删除&nbsp;&nbsp;</span></li><li class="alt"><span>db.delete('mytable',&nbsp;where="id=10")&nbsp;&nbsp;</span></li><li class=""><span>&nbsp;&nbsp;</span></li><li class="alt"><span>&nbsp;&nbsp;</span></li><li class=""><span>复杂查询&nbsp;&nbsp;</span></li><li class="alt"><span>#&nbsp;count&nbsp;&nbsp;</span></li><li class=""><span>results&nbsp;=&nbsp;db.query("SELECT&nbsp;COUNT(*)&nbsp;AS&nbsp;total_users&nbsp;FROM&nbsp;users")&nbsp;&nbsp;</span></li><li class="alt"><span>print&nbsp;results[0].total_users&nbsp;&nbsp;</span></li><li class=""><span>#&nbsp;join&nbsp;&nbsp;</span></li><li class="alt"><span>results&nbsp;=&nbsp;db.query("SELECT&nbsp;*&nbsp;FROM&nbsp;entries&nbsp;JOIN&nbsp;users&nbsp;WHERE&nbsp;entries.author_id&nbsp;=&nbsp;users.id")&nbsp;&nbsp;</span></li><li class=""><span>#&nbsp;防止SQL注入可以这么干&nbsp;&nbsp;</span></li><li class="alt"><span>results&nbsp;=&nbsp;db.query("SELECT&nbsp;*&nbsp;FROM&nbsp;users&nbsp;WHERE&nbsp;id= name")&nbsp;&nbsp;</span></li><li class="alt"><span>results&nbsp;=&nbsp;db.select('mytable',&nbsp;where="id&gt;100")&nbsp;&nbsp;</span></li><li class=""><span>#&nbsp;查询具体列&nbsp;&nbsp;</span></li><li class="alt"><span>results&nbsp;=&nbsp;db.select('mytable',&nbsp;what="id,name")&nbsp;&nbsp;</span></li><li class=""><span>#&nbsp;order&nbsp;by&nbsp;&nbsp;</span></li><li class="alt"><span>results&nbsp;=&nbsp;db.select('mytable',&nbsp;order="post_date&nbsp;DESC")&nbsp;&nbsp;</span></li><li class=""><span>#&nbsp;group&nbsp;&nbsp;</span></li><li class="alt"><span>results&nbsp;=&nbsp;db.select('mytable',&nbsp;group="color")&nbsp;&nbsp;</span></li><li class=""><span>#&nbsp;limit&nbsp;&nbsp;</span></li><li class="alt"><span>results&nbsp;=&nbsp;db.select('mytable',&nbsp;limit=10)&nbsp;&nbsp;</span></li><li class=""><span>#&nbsp;offset&nbsp;&nbsp;</span></li><li class="alt"><span>results&nbsp;=&nbsp;db.select('mytable',&nbsp;offset=10)&nbsp;&nbsp;</span></li><li class=""><span>&nbsp;&nbsp;</span></li><li class="alt"><span>&nbsp;&nbsp;</span></li><li class=""><span>更新&nbsp;&nbsp;</span></li><li class="alt"><span>db.update('mytable',&nbsp;where="id&nbsp;=&nbsp;10",&nbsp;value1&nbsp;=&nbsp;"foo")&nbsp;&nbsp;</span></li><li class=""><span>&nbsp;&nbsp;</span></li><li class="alt"><span>&nbsp;&nbsp;</span></li><li class=""><span>删除&nbsp;&nbsp;</span></li><li class="alt"><span>db.delete('mytable',&nbsp;where="id=10")&nbsp;&nbsp;</span></li><li class=""><span>&nbsp;&nbsp;</span></li><li class="alt"><span>&nbsp;&nbsp;</span></li><li class=""><span>复杂查询&nbsp;&nbsp;</span></li><li class="alt"><span>#&nbsp;count&nbsp;&nbsp;</span></li><li class=""><span>results&nbsp;=&nbsp;db.query("SELECT&nbsp;COUNT(*)&nbsp;AS&nbsp;total_users&nbsp;FROM&nbsp;users")&nbsp;&nbsp;</span></li><li class="alt"><span>print&nbsp;results[0].total_users&nbsp;&nbsp;</span></li><li class=""><span>#&nbsp;join&nbsp;&nbsp;</span></li><li class="alt"><span>results&nbsp;=&nbsp;db.query("SELECT&nbsp;*&nbsp;FROM&nbsp;entries&nbsp;JOIN&nbsp;users&nbsp;WHERE&nbsp;entries.author_id&nbsp;=&nbsp;users.id")&nbsp;&nbsp;</span></li><li class=""><span>#&nbsp;防止SQL注入可以这么干&nbsp;&nbsp;</span></li><li class="alt"><span>results&nbsp;=&nbsp;db.query("SELECT&nbsp;*&nbsp;FROM&nbsp;users&nbsp;WHERE&nbsp;id= id”, vars={‘id’:10})  
      7.   
      8.   
      9. 多数据库操作 (web.py大于0.3)  
      10. db1 = web.database(dbn=’mysql’, db=’dbname1’, user=’foo’)  
      11. db2 = web.database(dbn=’mysql’, db=’dbname2’, user=’foo’)  
      12. print db1.select(‘foo’, where=’id=1’)  
      13. print db2.select(‘bar’, where=’id=5’)  
      14.   
      15.   
      16. 事务  
      17. t = db.transaction()  
      18. try:  
      19.     db.insert(‘person’, name=’foo’)  
      20.     db.insert(‘person’, name=’bar’)  
      21. except:  
      22.     t.rollback()  
      23.     raise  
      24. else:  
      25.     t.commit()  
      26.   
      27. # Python 2.5+ 可以用with  
      28. from __future__ import with_statement  
      29. with db.transaction():  
      30.     db.insert(‘person’, name=’foo’)  
      31.     db.insert(‘person’, name=’bar’)  
      select 查询
      
      
      
      
      

查询表

entries = db.select('mytable')

where 条件

myvar = dict(name="Bob")
results = db.select('mytable', myvar, where="name = $name")
results = db.select('mytable', where="id>100")

查询具体列

results = db.select('mytable', what="id,name")

order by

results = db.select('mytable', order="post_date DESC")

group

results = db.select('mytable', group="color")

limit

results = db.select('mytable', limit=10)

offset

results = db.select('mytable', offset=10)

更新
db.update('mytable', where="id = 10", value1 = "foo")

删除
db.delete('mytable', where="id=10")

复杂查询

count

results = db.query("SELECT COUNT(*) AS total_users FROM users")
print results[0].total_users

join

results = db.query("SELECT * FROM entries JOIN users WHERE entries.author_id = users.id")

防止SQL注入可以这么干

results = db.query("SELECT * FROM users WHERE id=$id", vars={'id':10})

多数据库操作 (web.py大于0.3)
db1 = web.database(dbn='mysql', db='dbname1', user='foo')
db2 = web.database(dbn='mysql', db='dbname2', user='foo')
print db1.select('foo', where='id=1')
print db2.select('bar', where='id=5')

事务
t = db.transaction()
try:
db.insert('person', name='foo')
db.insert('person', name='bar')
except:
t.rollback()
raise
else:
t.commit()

Python 2.5+ 可以用with

from future import with_statement
with db.transaction():
db.insert('person', name='foo')
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’);  
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,修改GET 方法如下:

[python] view plain copy
print ?
  1. def GET(self):  
  2.     todos = db.select(’todo’)  
  3.     print render.index(todos)  
def GET(self):
    todos = db.select('todo')
    print render.index(todos)

修改urls 变量:

[python] view plain copy
print ?
  1. urls = (  
  2.     ’/’‘index’)  
urls = (
    '/', 'index')

重新编辑index.html 文件如下:

  1. def&nbsp;with&nbsp;(todos)&nbsp;&nbsp;</span></span></li><li class=""><span>&lt;ul&gt;&nbsp;&nbsp;</span></li><li class="alt"><span> def&nbsp;with&nbsp;(todos)&nbsp;&nbsp;</span></span></li><li class=""><span>&lt;ul&gt;&nbsp;&nbsp;</span></li><li class="alt"><span> for todo in todos:  
  2.     <li id=”ttodo.id"&gt; todo.id"&gt; todo.title</li>  
  3. </ul>  
$def with (todos)
<ul>
$for todo in todos:
    <li id="t$todo.id"&gt;$todo.title</li>
</ul>

现在,可以访问”/“,如果显示”Learn web.py“,则祝贺你成功了!

现在,再让我们看看如何向数据库写入。在index.html 文件的尾部添加如下内容:

  1. <form method=“post” action=“add”>  
  2.    <p>  
  3.        <input type=“text” name=“title” />  
  4.        <input type=“submit” value=“Add” />  
  5.    </p>  
  6. </form>  
<form method="post" action="add">
   <p>
       <input type="text" name="title" />
       <input type="submit" value="Add" />
   </p>
</form>

修改code.py 文件的urls 变量如下:

[python] view plain copy
print ?
  1. urls = (  
  2.     ’/’‘index’,  
  3.     ’/add’‘add’  
  4. )  
urls = (
    '/', 'index',
    '/add', 'add'
)

在code.py 里添加一个类:

[python] view plain copy
print ?
  1. class add:  
  2.     def POST(self):  
  3.         i = web.input()  
  4.         n = db.insert(’todo’, title=i.title)  
  5.         web.seeother(’/’)  
class add:
    def POST(self):
        i = web.input()
        n = db.insert('todo', title=i.title)
        web.seeother('/')

web.input 使你能够方便地访问用户通过表单提交上来的变量。db.insert 用于向数据库的 “todo” 表插入数据,并且返回新插入行的ID。web.seeother 用于重转向到”/“。

提示:对于数据库的操作,还有db.transact(), db.commit(), db.rollback(),db.update()。

在web.py 里,还有web.input,web.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
print ?
  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()  
import web
from web import form

render = web.template.render('templates/')

urls = ('/', 'index')
app = web.application(urls, globals())

myform = form.Form( 
    form.Textbox("boe"), 
    form.Textbox("bax", 
        form.notnull,
        form.regexp('\d+', 'Must be a digit'),
        form.Validator('Must be more than 5', lambda x:int(x)>5)),
    form.Textarea('moe'),
    form.Checkbox('curly'), 
    form.Dropdown('french', ['mustard', 'fries', 'wine'])) 

class index: 
    def GET(self): 
        form = myform()
        # make sure you create a copy of the form by calling it (line above)
        # Otherwise changes will appear globally
        print(form.render())
        return render.formtest(form)

    def POST(self): 
        form = myform() 
        if not form.validates(): 
            print(form.render())
            return render.formtest(form)
        else:
            # form.d.boe and form['boe'].value are equivalent ways of
            # extracting the validated arguments from the form.
            return "Grrreat success! boe: %s, bax: %s" % (form.d.boe, form['bax'].value)

if __name__=="__main__":
    web.internalerror = web.debugerror
    app.run()

formtest.html 代码如下:

  1. def&nbsp;with&nbsp;(form)&nbsp;&nbsp;</span></span></li><li class=""><span>&nbsp;&nbsp;</span></li><li class="alt"><span><span class="tag">&lt;</span><span class="tag-name">div</span><span>&nbsp;</span><span class="attribute">align</span><span>=</span><span class="attribute-value">"center"</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></span></li><li class=""><span><span class="tag">&lt;</span><span class="tag-name">form</span><span>&nbsp;</span><span class="attribute">name</span><span>=</span><span class="attribute-value">"main"</span><span>&nbsp;</span><span class="attribute">method</span><span>=</span><span class="attribute-value">"post"</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;&nbsp;</span></span></li><li class="alt"><span> def&nbsp;with&nbsp;(form)&nbsp;&nbsp;</span></span></li><li class=""><span>&nbsp;&nbsp;</span></li><li class="alt"><span><span class="tag">&lt;</span><span class="tag-name">div</span><span>&nbsp;</span><span class="attribute">align</span><span>=</span><span class="attribute-value">"center"</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></span></li><li class=""><span><span class="tag">&lt;</span><span class="tag-name">form</span><span>&nbsp;</span><span class="attribute">name</span><span>=</span><span class="attribute-value">"main"</span><span>&nbsp;</span><span class="attribute">method</span><span>=</span><span class="attribute-value">"post"</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;&nbsp;</span></span></li><li class="alt"><span> if not form.valid: <p class=“error”>Try again, AmeriCAN:</p>  
  2. :form.render()&nbsp;&nbsp;</span></li><li class="alt"><span><span class="tag">&lt;</span><span class="tag-name">input</span><span>&nbsp;</span><span class="attribute">type</span><span>=</span><span class="attribute-value">"submit"</span><span>&nbsp;</span><span class="tag">/&gt;</span><span>&nbsp;&nbsp;</span></span></li><li class=""><span><span class="tag">&lt;/</span><span class="tag-name">form</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></span></li><li class="alt"><span><span class="tag">&lt;</span><span class="tag-name">div</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></span></li></ol></div><pre class="html" name="code" style="display: none;"> :form.render()&nbsp;&nbsp;</span></li><li class="alt"><span><span class="tag">&lt;</span><span class="tag-name">input</span><span>&nbsp;</span><span class="attribute">type</span><span>=</span><span class="attribute-value">"submit"</span><span>&nbsp;</span><span class="tag">/&gt;</span><span>&nbsp;&nbsp;</span></span></li><li class=""><span><span class="tag">&lt;/</span><span class="tag-name">form</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></span></li><li class="alt"><span><span class="tag">&lt;</span><span class="tag-name">div</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></span></li></ol></div><pre class="html" name="code" style="display: none;"> def with (form) <div align=”center”> <form name=”main” method=”post”> ifnotform.valid:<pclass=error>Tryagain,AmeriCAN:</p> i f n o t f o r m . v a l i d :< p c l a s s = ” e r r o r ” > T r y a g a i n , A m e r i C A N :< / p > :form.render() <input type=”submit” /> </form> <div>

    Linux 下运行结果



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











                <script>
            $(".MathJax").remove();
        </script>
        <script type="text/javascript" src="//static-blog.csdn.net/mdeditor/public/res/bower-libs/MathJax/MathJax.js?config=TeX-AMS-MML_HTMLorMML"></script>
    </div>
  • 2
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值