web.py学习笔记

web.py是一个轻量级的python web框架,简单而且功能强大。相对flask和django,web.py更适合初学者来学习和了解web开发的基础知识。这篇文章记录一下web.py的学习过程。

开始

安装我直接就是pip install web.py,这样会安装最新版本的web.py,好像是0.39版本。更具体的还是参考官网http://webpy.org/install

至于教程就不废话了,官网上的应该足够了,说多了都是多余,就是这个网址,还有一个中文网址,这好像是直接拿谷歌翻译转的,看起来还不如英文的好理解。

不废话,直接录代码吧。

hello

hello.py

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
import web
render = web.template.render('templates/')
urls = (
'/hello1', 'hello1',
'/hello2', 'hello2',
'/hello3/(.*)', 'hello3',
)
class hello1:
def GET(self):
return 'hello1'
class hello2:
def GET(self):
i = web.input(name=None)
return render.hello(i.name)
class hello3:
def GET(self, name):
return render.hello(name)
if __name__ == '__main__':
app = web.application(urls, globals())
app.run()

templates/hello.html

1
2
3
4
5
$def with (name)
$if name:
I just wanted to say <em>hello</em> to $name.
$else:
<h2>hello, world.</h2>

运行

1
2
python hello.py #默认用8080端口
python hello.py 1234 #指定1234端口

访问几个url测试下效果:

1
2
3
4
5
http://localhost:8080/hello1
http://localhost:8080/hello2
http://localhost:8080/hello2?name=bruce
http://localhost:8080/hello3/
http://localhost:8080/hello3/bruce

web.py使用数据库

web.py推荐使用的数据库一般是mysqlpostgres,这两个对我这种初学者来说还是有点奢侈,于是我选了sqlite,因为它不用安装,对python2.7来说开箱即用,只需import sqlite3

sqlite客户端工具

我是linux系统,直接敲入sqlite3命令就好了(系统默认安装),如果想顺带打开数据库,可以这样sqlite3 test.db。windows下安装也简单。

网上有篇sqlite、mysql和postgres的对比文章,有空看看。

下面上一段sqlite3命令代码,最终实现创建表,为web.py例子做准备:

1
2
3
4
5
6
7
8
9
10
11
12
13
.open test.db -- 打开数据库
.databases -- 查看数据库
.tables -- 查看表
-- 创建user表
CREATE TABLE user(
id integer primary key autoincrement,
username char(10) not null unique,
password varchar(100) not null);
.schema user -- 查看建表语句
insert into user(username,password) values('aaa','111');
insert into user(username,password) values('bbb','111');
select * from user;
.quit -- 退出sqlite命令

用户注册

code1.py

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
import web
render = web.template.render('templates/')
db = web.database(dbn='sqlite', db='test.db')
urls = (
'/', 'index',
'/regist', 'regist'
)
class index:
def GET(self):
i = web.input(id=None)
if i.id:
users = db.select('user', where='id=$id', vars={'id':i.id})
else:
users = db.select('user')
return render.index1(users)
class regist:
def GET(self):
return render.regist()
def POST(self):
i = web.input()
n = db.insert('user', username=i.username, password=i.password)
raise web.seeother('/')
if __name__ == '__main__':
app = web.application(urls, globals())
app.run()

templates/index1.html

1
2
3
4
5
$def with (users)
<ul>
$for user in users:
<li id="u$user.id">$user.username</li>
</ul>

templates/regist.html

1
2
3
4
5
<form method="post" action="regist">
username:<input type="text" name="username" /><br>
password:<input type="password" name="password" /><br>
<input type="submit" />
</form>

测试一下上面的例子,是可以的。这里记录一下上面获得的users对象可以用uers.list()转成列表,然后就可以进行list的相关操作了。

python操作数据库

本节跟web.py无关,只是看到web.py要操作数据库,顺便记录一下python下的操作数据库的方法。

python操作数据库是我用过的编程语言最方便的,一个cursor包打天下。oracle、mysql、sqlserver、sqlite…我们能想到的关系型数据库,只要安装了相应模块后,除了连接参数不同,其他操作都是一样的。这点就像java的JDBC操作数据库那样,很方便。

下面,以sqlite为例,演示一下python操作数据库:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
import sqlite3 #默认安装,其他数据库没这待遇
conn = sqlite3.connect('test.db') #打开数据库,没有就创建
c = conn.cursor() #获得数据库操作游标,以后就靠它了
# 建表,后面的操作都一样,就是执行sql语句,就不注释了
c.execute('create table person(name char(10),age int)')
c.execute("insert into person(name,age) values('aaa',11)")
c.execute("insert into person(name,age) values('bbb',12),('ccc',13)")
p=('ccc',22)
c.execute('insert into person(name,age) values(?,?)',p)
rs=c.execute('select * from person')
for r in rs: print r[0]
c.execute("update person set name='ddd' where age=22")
c.execute('delete from person where age>20')
conn.commit() #提交数据库
conn.close() #关闭数据库

静态文件

z直接引用官方文档里的一段话:

Create a directory (also known as a folder) called static in the location of the script that runs the web.py server. Then place the static files you wish to serve in the static folder.

看个例子:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# -*- coding: UTF-8 -*-
import web
page="""
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
</head>
<body>
<img src="static/drogba1.png" />
</body>
</html>
"""
urls = ("/.*", "hello")
app = web.application(urls, globals())
class hello:
def GET(self):
return page
if __name__ == "__main__":
app.run()

RESTful

我暂且这么理解:restful就是服务端实现了GET、POST、PUT、DELETE方法且每个方法返回都是json串。那么,web.py如何实现restful?

先看一个例子:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
import json
def myinfo():
name = 'lcy'
age = 33
male = True
female = False
family = ['papa', 'mama', 'wife', 'son']
pet = None
print json.dumps(name)
print json.dumps(age)
print json.dumps(male)
print json.dumps(female)
print json.dumps(family)
print json.dumps(pet)
return json.dumps(locals())
if __name__ == '__main__':
jsonstr = myinfo()
print jsonstr
myinfo1 = json.loads(jsonstr)
print myinfo1

然而这个例子并木有什么用,这里只是记录下python如何操作json。

然后看一个web.py实现rest的例子:code.py

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
import web
import json
urls = ('/', 'Person')
app = web.application(urls, globals())
if __name__ == '__main__':
app.run()
class Person:
def GET(self):
return '{"name":"aaa","age":12}'
def POST(self):
name = web.input('first', 'last')
d = {}
d['firstname'] = name.first
d['lastname'] = name.last
s = json.dumps(d)
return s
def DELETE(self):
return '"delete"'
def PUT(self):
return '"put"'

运行python code.py启动web服务。然后我们来测试一下,从浏览器输入http://localhost:8080/看下结果,返回的是GET方法的结果。

坏了,POST、DELETE和PUT方法怎么测?我当然先想到的是无所不能的curl,试试:

1
2
3
4
5
curl -XGET "http://localhost:8080/"
curl -XPOST "http://localhost:8080/" -d "first=bruce&last=lee"
curl -XPOST "http://localhost:8080/?first=bruce&last=lee" #和上面一样
curl -XPUT "http://localhost:8080/"
curl -XDELETE "http://localhost:8080/"

测试成功,web服务后台分别调了相应方法。但是,干这种事情我python还要借助你curl么,开玩笑。先来个简便的:

1
2
3
4
5
6
7
#pip install httplib2
import httplib2
http = httplib2.Http()
http.request('http://localhost:8080/', 'GET')
http.request('http://localhost:8080/', 'POST', 'first=bruce&last=lee')
http.request('http://localhost:8080/', 'PUT')
http.request('http://localhost:8080/', 'DELETE')

再来一个不用httplib2的稍微繁琐一点的例子:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
import urllib
import urllib2
url = 'http://localhost:8080/'
#测试GET
res = urllib2.urlopen(url)
print res.read()
#测试POST
name = {'first':'aaa', 'last':'bbb'}
data = urllib.urlencode(name)
req = urllib2.Request(url, data)
res = urllib2.urlopen(req)
print res.read()
#测试PUT
req = urllib2.Request(url)
req。get_method = lambda:'PUT'
res = urllib2.urlopen(req)
print res.read()
#测试DELETE
req = urllib2.Request(url)
req。get_method = lambda:'DELETE'
res = urllib2.urlopen(req)
print res.read()

参考文章:http://webpy.org/cookbook/restful_doctesting_using_requesthttp://blog.chinaunix.net/uid-26000296-id-4394470.htmlhttps://blog.csdn.net/d_yang/article/details/2959530

学习资料

https://blog.csdn.net/freeking101/article/details/53020865
https://piaosanlang.gitbooks.io/web-py/content/index.html

总结

以后有什么需要记录的web.py学习过程遇到的问题,就在这上面吧。