Web.py入门


  1. 安装

安装web.py, 请先下载:

http://webpy.org/static/web.py-0.37.tar.gz

或者获取最新的开发版:

https://github.com/webpy/webpy/tarball/master

解压并拷贝 web 文件夹到你的应用程序目录下。

或者,为了让所有的应用程序都可以使用,运行:

python setup.py install

注意: 在某些类unix系统上你可能需要切换到root用户或者运行:

sudo python setup.py install

查看:推荐设置

另外一个选择是使用Easy Install。Easy Install 使用如下:

easy_install web.py

或者 PIP

sudo pip install web.py

  1. 样例

web.py 内置了web服务器。可以按照 tutorial 学习如何写一个Web应用。 写完后,将你的代码放到 code.py 文件中并如下面的方法来启动服务器:

python code.py

打开你的浏览器输入 http://localhost:8080/ 查看页面。 若要制定另外的端口,使用 python code.py 1234。

这里有一点是要注意,如果是根据链接 http://webpy.org/tutorial2 这个文章写出的代码是这个样子的:

import web
urls = (
  '/', 'index'
)
class index:
    def GET(self):
        print "Hello, world!"

if __name__ == "__main__": web.run(urls, globals())

运行话会报下面的错误:

D:devwww>python code.py
Traceback (most recent call last):
File “code.py”, line 8, in <module>
if __name__ == “__main__”: web.run(urls, globals())
AttributeError: ‘module’ object has no attribute ‘run’
</module>

我们应该根据下面的链接写hello word http://webpy.org/docs/0.3/tutorial 代码如下:

import web
urls = (
    '/', 'index'
)
class index:
    def GET(self):
        return "Hello, world!"
if __name__ == "__main__":
    app = web.application(urls, globals())
    app.run()

运行:D:devwww>python code.py

然后浏览器访问:http://127.0.0.1:8080/    看到hello, world!我们就成功了!

第一次配置的时候,不知道例子代码该如何写,写了个code.py和web.py,理所当然的报错;

第二次直接复制上面的代码存为web.py然后执行命令“python web.py”报错“AttributeError: ‘module’ object has no attribute ‘application’” 后来在stackoverflow上找到一点提示:You are runing into name collisions. You named your package web, and are trying to import a module web. 命名冲突错误,不能将自己写的代码命名为web.py。

  1. 一些解释
URL 处理

任何一个网站最重要的部分都是它的 URL 结构,URLs 不仅仅用来让网站的访问者看到或者 email 告诉他们的朋友,它还告诉别人你的网站是按照怎样的思维模式工作的。像 del.icio.us 这样的网站,它的 URLs 甚至是用户界面的一部分。web.py 让使用很棒的 URLs 变得很容易。

下面开始写基于 web.py 的应用程序,新建一个文本文件(让我们给它起名 code.py )并且输入:

import web

这句话的作用是引入 web.py 模块。

现在需要告诉 web.py 我们的 URL 结构。刚开始我们写个简单的:

urls = (
  '/', 'index'
)

第一部分是一个正则表达式,它用来匹配一个 URL,例如 /,/help/faq,/item/(d+) 等等。(d+ 匹配的是一串数字。括号表示匹配上部分供以后使用),第二部分是处理请求的类的名字,例如 index,view,welcome.hello(welcomes 模块的 hello 类),或者 get_1。1 用来被正则表达式捕捉到的第一部分替换,捕捉到的剩下的部分被传递给方法。

这一行的意思是我们把 URL 是 /(例如说首页)的请求传给 index 类来处理。

现在我们需要写 index 类。大部分人上网只是随便看看,他们不会注意到浏览器用的是一种被称为 HTTP 的语言与 World Wide Web 进行交流。这其中的细节不重要,但是有一个基本的概念,网站访问者让服务器根据 URLs(例如 / 或者 /foo?f=1)处理相应的动作(例如 GET或 POST)。

GET 动作我们很熟悉,它被用来请求一个文本形式的网页。当你在浏览器地址栏输入 harvard.edu 后,它会 GET 哈佛大学网站服务器的/。POST 动作我们也不陌生,它经常被用来提交相应的表单,例如一个购买东东的请求。只要你在网上做一个提交请求的动作(比方说用信用卡下一个定单),你就会用到 POST。了解这两个动作的不同之处很关键,因为 GET 方式的 URLs 可以被传送和被搜索引擎索引,你一定希望你网站上大部分的网页被索引,但是你也一定不希望正在处理的定单被索引(想象一下如果 Google 试图购买你网站上所有的东东!)。

在 web.py 代码里,我们把这两个动作区别得很清楚:

class index:
    def GET(self):
        print "Hello, world!"

只要有人提给服务器一个 URL 为 / 的 GET 请求,上面的 GET 方法将被 web.py 调用。

好了,现在我们需要完成程序的最后一行,告诉 web.py 开始提供网页服务:

if __name__ == "__main__": web.run(urls, globals())

这句话是让 web.py 在这个文件(code.py)的全局名称空间里查找相应的类给上面列出的 URLs 提供相应的服务。

现在请注意,尽管我在这儿叽叽歪歪讲了一大堆,可是我们实际上就写了 5 行代码。这就是我们写一个完整的 web.py 应用程序所需要的全部。如果你去命令行窗口输入:

$ python code.pyLaunching server: http://0.0.0.0:8080/

现在你的 web.py 应用程序就运行在一个真实的 web server 中了。访问那个 URL(http://localhost:8080),你应该看到“Hello, world!”(你可以在命令行的 code.py 后面添加 IP 地址/端口来控制 web.py 启动 server 的位置。你也可以使用 fastcgi 或者 scgi 参数来运行相应类型的服务。)

模版

在 Python 里面写 HTML 是非常让人厌倦的;而在 HTML 里面写 Python 则要有意思的多。幸运的是,web.py 让这一切变得很简单。

让我们为模版新建一个目录(目录名是templates。我们再在这个目录里新建一个扩展名是 html 的文件(我们叫它 index.html)。现在,你可以在这个文件里写普通的 HTML:

<em>Hello</em>, world!

或者你可以用 web.py 的模版语言往 html 文件里添加代码:

$def with (name)

$if name:
    I just wanted to say <em>hello</em> to $name.
$else:
    <em>Hello</em>, world!

注意:现在代码里需要有 4 个空格的缩进。

正如你看到的,除了顶部有 def with 的声明(saying what the template gets called with以及每行代码开头都有 $ 外,这个模版有点像 Python 文件。目前,template.py 要求 $def 声明在文件的第一行。而且请注意,web.py 会自动转义在这儿使用的任何变量,这样,如果为了某种需要,name 被赋成一个包含 HTML 的值,它将得到正确地转义并作为平文本显示出来。如果你想关掉这个功能,用$:name 代替 $name。

现在回到 code.py,在第一行下面加上:

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

这名话的意思是告诉 web.py 在 templates 目录中寻找模版文件。然后把 index.GET 改成:

name = 'Bob'print render.index(name)

访问你的站点,它应该变为 say hello to Bob 了。

小技巧:把 cache=False 加在 render 的语句后面,这样你每次访问页面时 web.py 都会重新加载模版文件。

现在改变 URL 那一行语句为:

'/(.*)', 'index'

接着改 index.GET 的定义为:

def GET(self, name):

然后删除给 name 赋值的语句。访问 / ,页面应该是 say hello to the world。访问 /Joe ,页面应该是 say hello to Joe。

数据库交互

在 web.run 这一句之上添加:

web.config.db_parameters = dict(dbn='postgres', user='username', pw='password', db='dbname')

(按照你自已的设置调整这些参数——特别是 username,password 和 dbname,MySQL 的用户需要把 dbn 的值改成 mysql。还有就是host,对于MySQLdb来说,使用localhost可能会报错,需要手动修改为127.0.0.1

在你的数据库里创建一个简单的表:

CREATE TABLE todo (
  id serial primary key,
  title text,
  created timestamp default now(),
  done boolean default 'f'
);

并且添加一条初始的条目:

INSERT INTO todo (title) VALUES ('Learn web.py');

回到 code.py ,改变 index.GET 为:

def GET(self):
    todos = web.select('todo')
    print render.index(todos)

再把处理 URL 的语句改回成 /。

按下面代码编辑 index.html:

$def with (todos)
<ul>
$for todo in todos:
    <li id="t$todo.id">$todo.title</li>
</ul>

访问你的站点,你应该可以看到一条 todo 项目:“Learn web.py”。恭喜!你已经有一个读数据库的完整的应用程序了。

在 index.html 文件末尾添加:

<form method="post" action="add">
<p><input type="text" name="title" /> <input type="submit" value="Add" /></p>
</form>

然后改你的 URLs 列表为:

'/', 'index',
'/add', 'add'

对逗号的使用你要非常小心。如果你忽略它们,Python 将把这些字符串合在一起,你的 URLs 列表将变成’/index/addadd’!)

现在再写一个类:

class add:
    def POST(self):
        i = web.input()
        n = web.insert('todo', title=i.title)
        web.seeother('./#t'+str(n))

(注意在这里我们是怎样应用 POST 的?)

web.input 让你得到用户通过提交表单传递给你的所有变量。web.insert 把值插入到数据库中的 todo 表中并且返回新条目的 ID 。seeother重定向用户到这个 ID。

速览:web.transact() 开启一个事务(transaction)。web.commit() 提交这个事务;web.rollback() 回滚这个事务。web.update 跟web.insert 差不多,但是它不是返回 ID 而是 it takes it(或者一个 WHERE 子句)after the table name.

web.input,web.query 和 web.py 中的其它一些方法可以返回“存储对象(Storage objects)”,它就像字典(dictionaries),你可以写d.foo 也可以写 d[‘foo’]。这确实使代码变得干净整洁。

你可以在这篇文档里找到关于这些的全部细节和 web.py 的所有方法。

现在教程结束了。阅读这篇文档吧,你可以用 web.py 做更多更酷的事情。

 

参考链接:


《“Web.py入门”》 有 1 条评论

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注