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 的简单而强大:
- 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()
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 模块:
- import web
- urls = (
- '/', 'index' )
/
、/help/faq
、/item/(\d+)
等(\d+
将匹配数字)。圆括号表示捕捉对应的数据以便后面使用。第二部分是接受请求的类名称,像index
、view
、welcomes.hello
(welcomes
模块的hello
类),或者get_\1
。\1
会被正则表达式捕捉到的内容替换,剩下来捕捉的的内容将被传递到你的函数中去。(‘index’)是一个类名,匹配的请求将会被发送过去。这行表示我们要URL/(首页)被一个叫index的类处理。现在我们需要创建一个列举这些 url 的 application。
- 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 代码中。我们清晰区分这两种方法:
- class index:
- def GET(self):
- print "Hello, world!"
- if __name__ == "__main__":
- app.run()
整个 code.py 文件的内容如下:
- 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()
3.启动服务
在你的命令行下输入:- $ python code.py # 使用默认端口 8080
- 或者
- $ python code.py 10000 # 改变端口为 10000
修改默认端口
在启动服务器的时候,如果你不想使用默认端口,你可以使用这样的命令来指定端口号: python code.py 8888。
4. 调试
直接添加一行 web.internalerror = web.debugerror 即可。如下
- 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文件。内容如下:
- 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 文件内容如下:
- <em>Hello</em>, world!
index_2.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” 的下一行添加:
- render = web.template.render('templates/')
然后再修改使用这个模板的类,在这里 修改 类 hello_1 和 类 hello_2
- class hello_1:
- def GET(self):
- return render.index_1()
- class hello_2:
- def GET(self, name):
- # name = "Lisa"
- return render.index_2("Lisa")
同时修改urls为:
- urls = (
- # '/(.*)', 'hello',
- '/hello_1[/]?.*', 'hello_1',
- '/hello_2/(.*)', 'hello_2',
- )
- def GET(self,name):
- print render.index_2(name)
Hello,
world
的字样。hello_2/ 页面调用 hello_2 类,使用 index_2.html 模板,打开 http://localhost:8080/hello_2/,页面就会打印出
Hello,
Lisa
的字样。除此之外还有两种使用模板的方法
- 使用frender直接指定模板文件。GET函数最后两行改为
- render=web.template.frender("templates/index.html")
- return render("Lisa")
- 直接在代码里写出模板文件。GET最后两行改为
- template = "$def with (name)\nHello $name"
- render = web.template.Template(template)
- return render("Lisa")
模板含义
现在解释一下这个 index.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>
而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对象的引用而发生错误。另如果像如下定义两个数字型对象:
- $varb = 1
- $varc = 2
注释
模板中支持单行注释,以$#符号开始到行末都是注释内容。
$#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 循环:
- $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 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: 本循环的外层循环对象
- $for a in ["a", "b", "c", "d"]:
- $loop.index,$loop.index0,$loop.first,$loop.last,$loop.odd,$loop.even,$loop.parity<br/>
- 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,只是也要在前面加$,代码也要注意$的使用和缩进:
- $def hello(name=""):
- Hello $name!
- $hello("Lisa")
- $def hello(name=""):
- <strong/>Hello $name!</strong>
- $:hello("Lisa")
输出程序代码-$code块
如果想在模板里输入写一段python代码而又不想被$所烦恼,那么可以用到$code块。
页面上输出一段代码而不希望被系统理解为模板程序代码,就需要用到$code命令,比如在模板文件中写入下面一段:
- $code:
- x=10
- def print_num(num):
- return "num is %d" % num
- $print_num(x)
- <br/>
- $x
然后下一行直接引用x变量,直接在页面上输出数字10。
$var
$var命令可以在模板中定义变量,在其他地方引用此模板对象的时候可以访问此定义的变量。
比如我们可以在index.html中添加如下一行:$var vara: this is vara
表示定义了一个名为vara的变量,变量值是字符串this is vara。
把index的GET函数改为:
- def GET(self):
- render=web.template.render("templates")
- return render.index("Lisa", "Hayes").vara
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的时候显式指定所需要的功能函数。
- import web
- import markdown
- globals = {'markdown': markdown.markdown}
- render =web.template.render('templates', globals=globals)
- # disable all builtins
- render = web.template.render('templates', builtins={})
模板复用
当多个页面有着相同的结构框架的时候,为每一个页面单独维护一个模板就显得比较麻烦,web.py提供了一种简易的解决方法。
这时候就要用到创建render时使用base参数:
- render=web.template.render("templates",base="layout")
- return render.index("Lisa", "Hayes")
- $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>
- $def with(gname, fname)
- Hi, $(gname) $(fname)
在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,在里面写一个函数:
- def hello_from_m1(name=""):
- return "hello %s, this is module1" % name
并且修改GET函数中创建render的代码为:
- def GET(self):
- render=web.template.render("templates",base="layout",globals={"m1":module1})
- return render.index("Lisa")
最后在要使用此模块的模板中就可以用$m1来引用此模块了。比如在index.html中添加下面一行代码:$m1.hello_from_m1(gname)
就会调用module1中的hello_from_m1函数,在页面上打印出:hello Lisa, this is module1
在web.py模板中使用jQuery
在jQuery中$也是一个关键字,这样的话如果在模板中使用jQuery就会冲突,这时候只需要用$做一下转义就可以了,比如:
- <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 来安装。
连接数据库:
- import web
- db = web.database(dbn='postgres', db='mydata', user='dbuser', pw='')
- 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')
- 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');
- def GET(self):
- todos = db.select('todo')
- print render.index(todos)
- urls = (
- '/', 'index')
- $def with (todos)
- <ul>
- $for todo in todos:
- <li id="t$todo.id">$todo.title</li>
- </ul>
现在,再让我们看看如何向数据库写入。在index.html 文件的尾部添加如下内容:
- <form method="post" action="add">
- <p>
- <input type="text" name="title" />
- <input type="submit" value="Add" />
- </p>
- </form>
- urls = (
- '/', 'index',
- '/add', 'add'
- )
- class add:
- def POST(self):
- i = web.input()
- n = db.insert('todo', title=i.title)
- 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):
- 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 代码如下:
- $def with (form)
- <div align="center">
- <form name="main" method="post">
- $if not form.valid: <p class="error">Try again, AmeriCAN:</p>
- $:form.render()
- <input type="submit" />
- </form>
- <div>
Linux 下运行结果
然后根据上面内容开始改写 自己的网站
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
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.