http://webpy.org/tutorial3.zh-cn
http://blog.sina.com.cn/s/blog_69812f770100xrk6.html
git clonegit://github.com/webpy/webpy.git
git clone
cd webpy此外,也许您还需要安装 python-cheetah, python-flup
python setup.py build
sudo python setup.py install
# -*- coding: UTF-8 -*-
#!/usr/bin/python
import web
# URL 规则
urls = (
'/(.*)', 'hello'
)
# 应用程序
app = web.application(urls, globals())
class hello:
def GET(self, name):
if not name: name = 'world'
web.header('Content-Type', 'text/html; charset=UTF-8')
return '你好,' + '世界' + '!'
# 启动
if __name__ == "__main__":
app.run()
python code.py现在这个 web.py 应用程序就运行了一个 web 服务器默认监听 8080 端口了,在浏览器中访问 http://0.0.0.0:8080/,应该就可以看到 “您好,世界!” 了。
python code.py 0.0.0.0:8000或者,只接受 192.168.1.25 来的 8086 端口
python code.py 0.0.0.0:8000
import web urls = ( "/hello", "hello", "/magic/.*", "magic" ) app = web.application(urls, globals())
import web app = web.auto_application() class hello(app.page): def GET(self): return "hello, world!"
web.py 支持集成多个应用程序,或说将应用划分到多个子应用程序。
比如将 /blog 分出在 blog.py 里边import web urls = ( "", "reblog", "/(.*)", "blog", ) class reblog: def GET(self): raise web.seeother('/') class blog: def GET(self, path): return "blog " + path app_blog = web.application(urls, locals())在 code.py:
import web import blog urls = ( "/blog", blog.app_blog, "/(.*)", "index", ) class index: def GET(self, path): return "hello " + path app = web.application(urls, locals())
可以根据子目录来划分应用程序,
比如将 wiki.py , blog.py ,auth.py 分出来
import web import wiki import blog import auth mapping = ( "/wiki", wiki.app, "/blog", blog.app, "/auth", auth.app, ) app = web.subdir_application(mapping)
也可以根据子域名来划分应用程序,这可以方便做 virtual hosting
比如
www.example.com (和 example.com)是 mainsite
XXXX.example.com 是 usersite
import web import mainsite import usersite mapping = ( "(www\.)?example.com", mainsite.app, ".*\.example.com", usersite.app, ) app = web.subdomain_application(mapping)
import web urls = ( "/hello", "hello", ) app = web.application(urls, globals()) class hello: """Hello world example. >>> response = app.request("/hello") >>> response.data 'hello, world!' >>> response.status '200 OK' >>> response.headers['Content-Type'] 'text/plain' """ def GET(self): web.header('Content-Type', 'text/plain') return "hello, world!"
import unittest from helloworld import app class HelloWorldTest(unittest.TestCase): def testHelloWorld(self): response = app.request('GET', '/') self.assertEquals(response.data, 'hello, world!') self.assertEquals(response.headers['Content-Type'], 'text/plain') self.assertEquals(response.status, '200 OK') if __name__ == "__main__": unittest.main()
web.py 0.3 正式提供了基于 cookie 的 session 支持。
import web urls = ( "/count", "count", "/reset", "reset" ) app = web.application(urls, locals()) session = web.session.Session(app, web.session.DiskStore('sessions'), initializer={'count': 0}) class count: def GET(self): session.count += 1 return str(session.count) class reset: def GET(self): session.kill() return "" if __name__ == "__main__": app.run()
上边 Session 的 initializer 参数可以是 dict 或func,用来初始化 session。
web.py 的 session 存储有基于文件的 DiskStore 和基于数据库的 DBStore ,上边例子是DiskStore。
也可以使用基于数据库的 DBStore。
使用 DBStore session 前需要在数据库建表create table sessions ( session_id char(128) UNIQUE NOT NULL, atime datetime NOT NULL default current_timestamp, data text );然后就可以
db = web.database(dbn='postgres', db='mydatabase', user='myname', pw='') store = web.session.DBStore(db, 'sessions') session = web.session.Session(app, store, initializer={'count': 0})
可以用 web.setcookie() 、web.cookies() 来设置和读取 cookies
参数:web.setcookie(name, value, expires="", domain=None, secure=False)
class CookieSet: def GET(self): i = web.input(age='25') web.setcookie('age', i.age, 3600) return "Age set in your cookie"
web.cookies().get(cookieName) #cookieName is the name of the cookie submitted by the browser2. 有预设值,避免异常
foo = web.cookies(cookieName=defaultValue) foo.cookieName # return the value (which could be default) #cookieName is the name of the cookie submitted by the browser例子:
通过 web.cookies() 来访问
如果先前 web.setcookie() 设置了 age , 那可以这样读取
class CookieGet: def GET(self): c = web.cookies(age="25") return "Your age is: " + c.age上边的当没有 cookie 时会异常,如果要考虑没有 cookie 的情况,可以类似下边这样:
class CookieGet: def GET(self): try: return "Your age is: " + web.cookies().get('age') except: # Do whatever handling you need to, etc. here. return "Cookie does not exist."
先用 web.config 配置 smtp
web.config.smtp_server = 'smtp.gmail.com' web.config.smtp_port = 587 web.config.smtp_username = 'cookbook@gmail.com' web.config.smtp_password = 'secret' web.config.smtp_starttls = True
再用类似下边的发邮件
web.sendmail('cookbook@gmail.com', 'user@example.com', 'subject', 'message')或者可以附上邮件头
web.sendmail('cookbook@webpy.org', ['user@example.com', 'user2@example.com'], 'subject', 'message', cc='user1@example.com', bcc='user2@example.com', headers=({'User-Agent': 'webpy.sendmail', 'X-Mailer': 'webpy.sendmail',}) )
class example: def GET(self): referer = web.ctx.env.get('HTTP_REFERER', 'http://google.com') useragent = web.ctx.env.get('HTTP_USER_AGENT') raise web.seeother(referer)
web.py 支持模板(注意需要 python-cheetah)
先看看将 第一个程序 改为使用模板
写入 templates/hello.html :
$def with (name, todos={}) $if name: <h1>你好,$name!</h1> $else: <h1>你好,世界!</h1>
注意模板文件首行要个 $def with() ,
在 code.py 里用
render = web.template.render('templates/') class hello: def GET(self, name): return render.hello(name)
Look, a $string. Hark, an ${arbitrary + expression}. Gawk, a $dictionary[key].function('argument'). Cool, a $(limit)ing. Stop, \$money isn't evaluated.
We use basically the same semantics as (rejected) PEP215. Variables can go anywhere in a document.
If you put a backslash \ at the end of a line \ (like these) \ then there will be no newline.这会输出一整行
Here are some expressions: $for var in iterator: I like $var! $if times > max: Stop! In the name of love. $else: Keep on, you can do it. $try: $get(input) $except: Couldn't find it. That's all, folks.
$# Here's where we hoodwink the folks at home: Please enter in your deets: CC: [ ] $#this is the important one SSN: $#Social Security Number#$ [ ]$# 到行末的是注释
可以将 python 语句放在行首的 "$ " 后(从"$ " 开始,之道行尾,或下一个 "$" )
$def with() $ mapping = dict(a=[1, 2, 3], $ b=[4, 5, 6]) <b>$mapping['a'][0]</b>
len = 'cn' web.template.Template.globals[len] = len或者直接传递 globals()
web.template.Template.globals = globals()
也可以在 metaclass.func 里传递 locals()
class index: def GET(self): title = '你好,世界' entrys = ['第一个', '第二个', '第三个'] s = web.Storage(locals()) return render.index(s)而 templates/index.html 里用
$def with(s) ...<title>$s.title</title> ... <ul> $for entry in s.entrys: <li>$entry</li> </ul>
class SomePage: def GET(self): user_data = web.input(id=[]) return "<h1>" + ",".join(user_data.id) + "</h1>"
还可以使用web.data()来获取输入,但这两都有区别
import web urls = ('/upload', 'Upload') class Upload: def GET(self): return """<html><head></head><body> <form method="POST" enctype="multipart/form-data" action=""> <input type="file" name="myfile" /> <br/> <input type="submit" /> </form> </body></html>""" def POST(self): x = web.input(myfile={}) return "filename: %s\n value: \n%s" % (x['myfile'].filename, x['myfile'].value) if __name__ == "__main__": app = web.application(urls, globals()) app.run()
import web db = web.database(dbn='postgres', db='todo', user='you', pw='') db.select('todo') db.select('todo', where='id=$id', vars={'id': 2}) db.query('SELECT * FROM todo')