使用 web.py 创建一个 blog 系统

小编辑 发布于 2010/03/21 08:32
阅读 7K+
收藏 6

01、准备工作
先安装Python,然后安装web.py。
数据库我准备使用Python自带的sqlite,因此不用另安装其他数据库。
(我的运行环境是在Windows 2003下面,因为Python是跨平台的,所以理论上在Linux下面一样可行,但是我没有测试)
当前程序版本:Python 2.5.1,web.py 0.23。
(Python的官方网站:http://www.python.org (http://www.python.org/))
(web.py的官方网站:http://webpy.org (http://webpy.org/))
02、数据库
数据库我是用sqlite,主要是我并不会做一个大大大大的blog,用mysql是不是太浪费了?
而且sqlite现在python也集成了,用起来很方便。
(当然也可以用mysql,很流行的,如果想使用mysql的话,请搜一下“MySQLdb”)
(在web.py 0.23版本中,目前只支持3种数据库:postgres、mysql、sqlite)
那么不用数据库可不可以?当然可以。我其实很喜欢用txt文件,呵呵。
但是大家都用,我们最好也用。
(很久很久之后的将来,你会发现用数据库的好处)
我创建一个Python源程序文件:database.py,然后写一些代码来创建一个数据库,并插入一些文件。
代码如下:(有可能会串行,自己调整一下。因为我是在Opera下面来写所以造成串行的。在Safari下面也是)
# -*- coding: cp936 -*-
import sqlite3 # 导入sqlite模块
con = sqlite3.connect("blog.db") # 连接到数据库文件
cur = con.cursor() # 创建一个指针
cur.execute("create table user1 (date, number, article)") # 创建1个表格,并创建3个域
tt1 = ('2007-10-11', '1', 'aaa') # 准备要插入的数据
cur.execute("""insert into user1 (date, number, article) values(?,?,?)""", tt1) # 插入数据
tt2 = ('2008-01-19', '2', 'bbbbb') # 再插入一组数据
cur.execute("""insert into user1 (date, number, article) values(?,?,?)""", tt2)
tt3 = ('1997-03-25', '3', 'cc') # 再再插入一组数据
cur.execute("""insert into user1 (date, number, article) values(?,?,?)""", tt3)
con.commit() # 执行操作
cur.close() # 关闭指针
con.close() # 关闭数据库连接
如果你会SQL的话上面的东西就很好理解,不会的的话,也很好理解,是不是?
数据库的连接——关闭,指针的创建——关闭,先建立一个表格,表格中有域,可以插入数据。
(你用过Excel没有?差不多都是一样的)
有可能你不太理解为什么要把插入的数据写成('2007-10-11', '1', 'aaa')这样的。
这样的数据结构是一个tuple(元祖),据说这样可以防止“数据库的注入式漏洞”。
好了,运行一下database.py吧,会在同目录下出现一个文件“blog.db”。这就是我们的数据库!
(最好能看一下Python Library Reference的13.13 sqlite3 -- DB-API 2.0 interface for SQLite databases)
(这里面会对python里面内置的sqlite3做一个简单但是非常有用的介绍)
03、第一个页面
我们现在来写第一个页面,看看web.py到底能不能跑起来。
代码如下:
import web
urls = (
'/', 'index',
)

class index:
def GET(self):
print 'index'
if __name__ == "__main__":
web.run(urls, globals())
保存为:blog_1.py。并运行之。
注意:一定要在命令提示符下运行!
可以在命令提示符下面看到:http://0.0.0.0:8080/,
打开IE,访问:http://127.0.0.1:8080/,
可以看到“index”了,是不是?
04、整体架构
现在让我们冷静一下,先想想我们要做的这个Blog的整体架构。
虽然我们要做个最最最简单的Blog,但是还是要先想好然后再动手。
首先,要能“显示”,能显示每个用户的文章、序号、以及日期。
然后,要能“登陆”,只有“登陆”之后才能“写文章”。
我就想到这两点,我认为这就是一个blog的雏形了。
那么我们需要几个页面呢?
第1个:主页面,显示所有用户的文章。
第2个:登陆页面,用户在这里输入用户名和密码
第3个:显示页面,显示某个用户的文章
第4个:编辑页面,用户在这里写新文章
(当然,有一些功能也很重要,比如“修改”,比如“图片”之类,慢慢来添加好不好?)
05、主页面
现在我们来做主页面,要能显示数据库中的数据。
我们直接来修改blog_1.py。
在import web这行代码的下面添加:
import sqlite3
把print 'index'这行代码删除,
添加:
con = sqlite3.connect("blog.db")
cur = con.cursor()
cur.execute('select * from user1')
for row in cur:
print row
cur.close()
con.close()
把这个文件另存为:blog_2.py。并运行之(记住要在命令提示符下运行)。
然后我们打开IE,输入:http://127.0.0.1:8080/
我看到了:(u'2007-10-11', u'1', u'aaa') (u'2008-01-19', u'2', u'bbbbb') (u'1997-03-25', u'3', u'cc')
你看到了没有?
06、主页面的第1次修改
其实blog_2.py是一个相当不成熟的例子,我想你也能感觉出来。
因为数据库不是这样用的,web.py是一个框架(Framework),
它提供了数据库和模板的方便调用方法,这也是我们使用框架的原因。
现在让我们来使用数据库吧。
我们直接修改blog_1.py文件。
先在:web.run(urls, globals())这一行上面添加:
web.config.db_parameters = dict(dbn='sqlite', db='blog.db')
(这一行代码是配置数据库的,mysql的话还需要添加用户名和密码)
其中dbn表示数据库的名称,我们填入sqlite;
db表示具体数据库的文件名称,我们填入blog.db。
(注意:一定要加后缀名)
然后把print 'index'这行代码删除,
添加新的代码:
user1 = web.select("user1")
print user1[0].date
print len(list(user1))
(第1行是遍历出整个user1表,第2行显示user1表的第1个元素的number值,第3行显示user1表的长度)
(关于第3行看上去会有点奇怪,但是如果你试着用len(user1)这样就会出错,请试着理解,这就是“数据库的方式”)
其中第1行可以改为user1 = web.query("select * from user1"),显示出来的东西会是完全一样的。
为什么呢?
因为本质上是一样的。但是web.query是用作查询之用的,最好还是专职专用。
(详细的还是要看C:\Python25\Lib\site-packages\web文件夹下面的db.py)
把这个文件另存为:blog_3.py。并运行之。
在127.0.0.1:8080下面我们应该能够看到:“2007-10-11 2”
其中“2007-10-11”是user1[0].date的值;
“2”是“数据库游标之后部分的长度”。
游标是什么呢?即cursor(游标,指针),它指向数据库的当前位置。
接下来,你可以试试把user1[0].number改成user1[1].number或者user[2].article,看看会显示出来什么。
07 主页面的第2次修改
我们试着来显示数据库中所有的元素。
直接修改blog_3.py,其实主要就是修改index类中的GET方法。代码如下:
class index:
def GET(self):
user1 = web.select("user1")
user1_len = len(list(user1)) #数据库长度
user1_date = web.select("user1") #得到日期
user1_number = web.select("user1") #得到序号
user1_article = web.select("user1") #得到文章内容
for i in range(0, user1_len):
print user1_date[i].date, \
user1_number[i].number, \
user1_article[i].article
另存为blog_4.py,并运行之,应该能看到:2007-10-11 1 aaa 2008-01-19 2 bbbbb 1997-03-25 3 cc
或者改为:
class index:
def GET(self):
user1 = web.select("user1")
user1_len = len(list(user1)) #数据库长度
user1_date = web.query("select date from user1") #得到日期
user1_number = web.query("select number from user1") #得到序号
user1_article = web.query("select article from user1") #得到文章内容
for i in range(0, user1_len):
print user1_date[i].date, \
user1_number[i].number, \
user1_article[i].article
另存,运行,得到的结果也和上面的一模一样。
主要区别在于调用的方法不同,一个是web.select一个是web.query。
(我看到别人写的一个程序,好像都是用的web.query)
虽然这样可以显示,不过好丑!
怎么办?用模板!
08 用模板
(模板的英文是templates)
我们一步一步来看看模板怎么用。
首先,先创建一个目录,名字就是templates。
然后,在这个目录里面创建一个文件,名字是index.html。
那么往这个index.html上面写些什么呢?
$def with (user1_date)
<html>
<head>
<title>blog</title>
</head>
<body>
$user1_date[0].date
</body>
</html>
在blog_4.py上面直接修改,在import web的下一行加上:
render = web.template.render('templates/')
然后另存为blog_5.py。
这主要是告诉程序模板文件的位置。
然后修改index类的GET方法,原先的代码统统删掉,新代码如下:
user1_date = web.query("select date from user1") #得到日期
print render.index(user1_date)
好了,现在保存,然后运行blog_5.py吧。
我看到了:2007-10-11
你呢?

加载中
0
William
William

能不能编辑下格式呀。。。

太乱了, 

0
引申
引申

这些代码是基于web.py 0.23的,对于现在而言有点古老,要使用需要改不少东西

0
K
KTC

出现一个问题,我用的是python2.6,web.py-0.37 按照hello world的方法输入后,在网页地址栏输入127.0.0.1:8080,结果那个hello world出现在python idle里,而网页里只有一个none,请问这是怎么回事?

import web

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

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

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

返回顶部
顶部