7. Python脚本学习实战笔记七 电子公告板

来源:互联网 发布:淘宝客领取内部优惠券 编辑:程序博客网 时间:2024/06/06 15:02

7. Python脚本学习实战笔记七 电子公告板

本篇名言:“不管生活如何变故,道路如何曲折,你千万别掉队,因为希望和梦想就在前面。”

1.  需求

如何创建通过网络发布和回复信息的简单系统.系统内有自己的一个作为论坛的机制。

2.  工具和准备

除了CGI工具外,

还需要一个SQL数据库,这里使用PostgreSQL数据库。

下载地址如下:

http://www.enterprisedb.com/products-services-training/pgdownload#windows

双击安装即可。

此外,还需要一个与PostgrelSQL数据库通信的API模块,使用psycopg即可。

下载链接如下

http://www.stickpeople.com/projects/python/win-psycopg/

注意Python版本号和 postgrelSQL的版本号。

双击安装后,进行导入 import psycopg2 即可判断是否正常。

 

2.1      创建数据库

数据库的结构和所要解决的问题联系的很紧密。

打开PostgrelSQL命令行模式如下图1


#create database bbs;

#\c bbs;

#CREATE TABLE messages (

   id          SERIAL PRIMARY KEY,

   subject     TEXT NOT NULL,

   sender      TEXT NOT NULL,

   reply_to    INTEGER REFERENCESmessages,

   text        TEXT NOT NULL

);

#\d

显示如下:

                    关联列表

 架构模式 |      名称       | 型别  |  拥有者

----------+-----------------+--------+----------

 public  | messages        | 资料表 |postgres

 public  | messages_id_seq | 序列数 | postgres

(2 行记录)

 

拥有5个字段,

Id用于标识唯一的消息
subject包括消息主体的字符串

Sender:包括发送者名字、EMAIL地址或者其他信息的字符串

Reploy_to :如果消息是回复其他消息的、那么这个字段就包括那个消息的ID

Text: 包括消息内容的字符串。

 

3.  初次实现

先进行一个简单那的测试:

>>> import psycopg2

>>>conn=psycopg2.connect('user=postgres password=huawei dbname=bbs')

>>> curs=conn.cursor()

>>> curs.execute('select * frommessages')

>>> curs.fetchall()

[]

所有信息为空,所以没有得到什么。

                  对于每个消息来说,获取reply_to字段,如果是None(不是回复),那么将这条消息添加到顶级消息的李彪。否则将其添加到children[parent_id]自列表中。

                  为顶级消息调用format函数。Format函数打印消息的主题。而且如果消息有任何回复的话,会打开一个blockquote元素,对于每一个回复调用format函数(递归),然后结束blockquote元素。

正式初次实现代码如下:

#!D:\python27\python.exe

 

print'Content-type: text/html\n'

 

importcgitb; cgitb.enable()

 

importpsycopg2

conn = psycopg2.connect('dbname=bbs user=postgres password=huawei')

curs = conn.cursor()

 

print"""

<html>

  <head>

    <title>The FooBar BulletinBoard</title>

  </head>

  <body>

    <h1>The FooBar BulletinBoard</h1>

    """

 

 

curs.execute('SELECT * FROM messages')

rows = curs.fetchall()

 

toplevel = []

children = {}

 

forrowin rows:

   parent_id = row['reply_to']

   if parent_idisNone:

        toplevel.append(row)

   else:

       children.setdefault(parent_id,[]).append(row)

 

defformat(row):

   print row['subject']

   try: kids =children[row['id']]

   except KeyError:pass

   else:

        print'<blockquote>'

        for kidin kids:

            format(kid)

        print'</blockquote>'

 

print'<p>'

 

forrowin toplevel:

   format(row)

 

print"""

    </p>

  </body>

</html>

"""

如果数据库为空,那么现实就是空白了,这个没关系,只要不报警即可。

4.  再次实现

架构WEB程序使用类似CGI技术,最简单的方法是对用户执行的每个操作写一个脚本。

对于本系统需要如下脚本:

                  Main.cgi,显示所有消息的主题

                  View.cgi,显示一篇文章

                  Edit.cgi,编辑的表单中显示一篇文章,页面的提交Sumbit按钮链接到能实现保存功能的脚本。

                  Save.cig,获取edit.cgi文章的信息,并将其作为新行插入到数据库的表中进行保存。

 

 

4.1      Main脚本

加入链接,每个主题都会连接到给定的消息(view.cgi).在页面的下方还会添加一个允许用户发布新消息的链接,连接到edit.cgi.

具体如下:

#!D:\python27\python.exe

 

print'Content-type: text/html\n'

 

importcgitb; cgitb.enable()

 

importpsycopg2

conn = psycopg2.connect('dbname=bbs user=postgres password=huawei')

curs = conn.cursor()

 

print"""

<html>

  <head>

    <title>The FooBar BulletinBoard</title>

  </head>

  <body>

    <h1>The FooBar Bulletin Board</h1>

    """

 

curs.execute('SELECT * FROM messages')

rows = curs.fetchall()

 

toplevel = []

children = {}

 

forrowin rows:

   parent_id = row[3]

   if parent_idisNone:

        toplevel.append(row)

   else:

        children.setdefault(parent_id,[]).append(row)

 

defformat(row):

   print'<p><ahref="view.cgi?id=%i">%s</a></p>' % (row[0],row[1])

   try: kids =children[row[0]]

   except KeyError:pass

   else:

        print'<blockquote>'

        for kidin kids:

            format(kid)

        print'</blockquote>'

 

print'<p>'

 

forrowin toplevel:

   format(row)

 

print"""

    </p>

    <hr />

    <p><a href="edit.cgi">Postmessage</a></p>

  </body>

</html>

"""

执行如下图2

点击Post message跳转到edit.cgi.

编辑后出现如下3

 

4.2      View脚本

代码如下:

#!D:\python27\python.exe

 

print 'Content-type: text/html\n'

 

import cgitb; cgitb.enable()

 

import psycopg2

conn = psycopg2.connect('dbname=bbs user=postgres password=huawei')

curs = conn.cursor()

 

import cgi, sys

form = cgi.FieldStorage()

id = form.getvalue('id')

 

print """

<html>

  <head>

    <title>ViewMessage</title>

  </head>

  <body>

    <h1>ViewMessage</h1>

    """

 

try: id = int(id)

except:

    print 'Invalid message ID'

    sys.exit()

 

curs.execute('SELECT * FROM messages WHERE id = %i' % id)

rows = curs.fetchall()

 

if not rows:

    print 'Unknown message ID'

    sys.exit()

 

row = rows[0]

 

print """

   <p><b>Subject:</b> %s<br />

    <b>Sender:</b>%s<br />

    <pre>%s</pre>

    </p>

    <hr />

    <ahref='main.cgi'>Back to the main page</a>

    | <ahref="edit.cgi?reply_to=%i">Reply</a>

  </body>

</html>

""" % (row[1],row[2],row[4],row[0])

 

 

4.3      Edit脚本

Edit.cgi 用于编辑新消息,也用于编辑回复。

如果提供了reply_to参数,那么会被保存在编辑表单的一个隐藏输入(hidden input)中。除此之外,主题会默认设定为“Re:parentsubject” ,除非主题已经以”Re:”

代码如下:

#!/usr/bin/python

 

print 'Content-type:text/html\n'

 

import cgitb; cgitb.enable()

 

 

import psycopg

conn =psycopg.connect('dbname=foo user=bar')

curs = conn.cursor()

 

import cgi, sys

form = cgi.FieldStorage()

reply_to =form.getvalue('reply_to')

 

print """

<html>

  <head>

   <title>Compose Message</title>

  </head>

  <body>

    <h1>Compose Message</h1>

 

    <form action='save.cgi'method='POST'>

    """

 

subject = ''

if reply_to is not None:

    print '<input type="hidden"name="reply_to" value="%s"/>' % reply_to

    curs.execute('SELECT subject FROM messagesWHERE id = %s' % reply_to)

    subject = curs.fetchone()[0]

    if not subject.startswith('Re: '):

        subject = 'Re: ' + subject

 

print """

    <b>Subject:</b><br />

    <input type='text' size='40' name='subject'value='%s' /><br />

    <b>Sender:</b><br />

    <input type='text' size='40'name='sender' /><br />

    <b>Message:</b><br />

    <textarea name='text' cols='40'rows='20'></textarea><br />

    <input type='submit' value='Save'/>

    </form>

    <hr />

    <a href='main.cgi'>Back to the mainpage</a>'

  </body>

</html>

""" % subject

 

 

被调用后执行如下 图4

点击back to the main page调用main.cgi.

点击save调用save.cgi.

如下图5

4.4      Save脚本

 

 

 

脚本如下:

#!D:\python27\python.exe

 

print'Content-type: text/html\n'

 

importcgitb; cgitb.enable()

 

defquote(string):

   if string:

        return string.replace("'","\\'")

   else:

        return string

 

importpsycopg

conn = psycopg.connect('dbname=bbs user=postgres password=huawei')

curs = conn.cursor()

 

importcgi, sys

form = cgi.FieldStorage()

 

sender = quote(form.getvalue('sender'))

subject = quote(form.getvalue('subject'))

text = quote(form.getvalue('text'))

reply_to = form.getvalue('reply_to')

 

ifnot (senderand subjectand text):

   print'Please supply sender, subject, and text'

   sys.exit()

 

ifreply_toisnotNone:

   query = """

    INSERT INTO messages(reply_to, sender,subject, text)

    VALUES(%i, '%s', '%s','%s')""" % (int(reply_to), sender,subject, text)

else:

   query = """

    INSERT INTO messages(sender, subject, text)

    VALUES('%s', '%s', '%s')""" % (sender, subject, text)

 

curs.execute(query)

conn.commit()

 

 

print"""

<html>

  <head>

    <title>Message Saved</title>

  </head>

  <body>

    <h1>Message Saved</h1>

    <hr />

    <a href='main.cgi'>Back to themain page</a>

  </body>

</html>s

"""

 

在Edit.cgi中点击保存,出现如下图6

 

点击Back to the main page 回到main.cgi脚本。

此时数据库出现如下内容图7

 

 

5.  交付

代码在链接处可以下载:

http://download.csdn.net/detail/notbaron/8965175

放置到cgi-bin解压即可。

6.  PostgrelSQL和MySQL常用命令

(1)列出所有的数据库

mysql: show databases

psql: \l或\list

(2)切换数据库

mysql: use dbname

psql: \c dbname

 

(3)列出当前数据库下的数据表

mysql: show tables

psql: \d

 

(4)列出指定表的所有字段

mysql: show columns from table name

psql: \d tablename

 

(5)查看指定表的基本情况

mysql: describe tablename

psql: \d+ tablename

 

(6)退出登录

mysql: quit 或者\q

psql:\q