关闭

自定义公告板

标签: cgi数据库表单url
582人阅读 评论(0) 收藏 举报
分类:

公告板,我理解的是不是门岗大爷旁边的那个,通知我们最近需要我们注意的事情,我想除了检查卫生没别的了,而且好久也不见更新,还有一个就是电子公告板,流水字那个,就是很多二极管组成的数码管来显示字的那种(而且需要流动的),当然这个项目不是这个,公告板就是显示信息来通知别人的,那么这些信息是存储在那的呢?进入公告标题,里面应该是其内容或者还有一些其他的信息,这篇是把信息存在数据库里。

先看看数据库中建的一个表吧:

create table messages(
id int not null auto_increment,
subject varchar(100) not null,
sender varchar(15) not null,
reply_to int,
text mediumtext not null,
primary key(id));
如代码所示,只是建了 id ,subject,sender,reply_to,text,等5个字段和各自的类型及最大字符串长度。其中主键是id.

作为一个公告板,一定能显示信息和编辑信息吧。

先看看公告板的主页代码,所有通知的信息都应该在主页显示,不然该去哪看。

print 'Content-type:text/html\n'
print
#import cgitb:cgitb.enable()

import MySQLdb

conn = MySQLdb.connect(db='hu',user='root')

curs = conn.cursor()

print '''
<html>
  <head>
    <title>The hu yiyang</title>
  </head>
  <body>
    <h1>The hu yiyang </h1>
'''

curs.execute('SELECT * FROM messages')
rows = curs.fetchall()
toplevel = []
children = {}

for row in rows:
    parent_id = row[3]
    if parent_id is None:
        toplevel.append(row)
    else:
        children.setdefault(parent_id,[]).append(row)

    def format(row):
            print '<p><a href="view.cgi?id=%i">%s<a>' % 

(row[0],row[1])
            try:
                    kids = children[row[0]]
            except KeyError:
                    pass
	    else:
                    print '<blockquote>'
                    for kid in kids:
                            format(kid)

                    print '</blockquote>'

    print '<p>'

    for row in toplevel:
                format(row)

print '''
</p>
<hr/>
<p><a href="edit.cgi">Post Messages</a></p>
</body>
</html>
'''
刚开始与数据库进行连接,‘hu’是数据库名,‘root’是用户名。conn.cursor()是用来获取连接数据库的浮标,用于使用sql语句,下面就是打印一些信息,curs.execute()就是执行里面的sql语句,检索messages表中的所有字段信息,下面的curs.fetchall()就是把检索的信息按序列输出显示,下面这个for是处理有没有回复的消息,如果该主题没有人回复就把该行记录存储 在toplevel列表中,否则就吧该行记录记录到chilren字典中,其中setdefault函数的意思是如果parent_id有值(不是None),也就是有人回复信息,就把该行记录存储在children字典中(当然可以很多人回复消息,所以采用字典来存储),最终就是说没人回复的主题放在toplevel中,有人回复的放在children中。接着是format函数,主要进行对每一条记录显示的问题,     print '<p><a href="view.cgi?id=%i">%s<a>' % (row[0],row[1])的意思就是只要你点击某个主题,就会连接到其对应的内容里,然后又是捕捉异常的了,如果children[row['0']]有值,也就是说有回复信息,就会在该主题里显示出该回复信息,否则会引发一个KeyError异常,不过这个异常的执行是pass.,对应没人回复的信息也会执行一次format来链接显示这个主题。最后还有一个链接是Post messages,用于链接到编辑页面,edit.cgi.


下面看edit.cgi代码:

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

#import cgitb: cgitb.enable()

import MySQLdb
conn = MySQLdb.connect(db='hu',user='root')
curs = conn.cursor()
import cgi,sys

form = cgi.FieldStorage()
reply_to = form.getvalue('reply_to')
print """
<html>
    <head>
        <title>Compose Messages</title>
    </head>
    <body>
        <h1>Compose Messages</h1>

        <form action='/cgi-bin/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 messages WHERE 

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 main page</a>
    </body>
    </html>
    ''' % subject



刚开始都一样,都是链接存储信息的数据库,并且获取连接数据库的游标,以用于使用sql语句。cgi.FieldStorage()在上个项目就有,是用来获取上个页面提交过来的信息(也就是main.cgi),先获取字段名为‘reply_to’的信息(他中存储的是被回复那个主题的ID),存储到reply_to中,下面也是一个打印本页标题的html,   <form action='/cgi-bin/save.cgi' method='POST'>就是一个提交表单,要跳转的页面,action的值可以是本站点的url地址,也可以是其他站点的。如果有回复的信息,就把名为‘reply_to’,值为‘ 被回复主题的ID ’的信息隐藏起来(编辑该主题的时候并不需要看该主题的回复情况吧),接着是执行一条sql语句,意思是检索 messages表中id为reply_to的值的主题(就是查找被回复的那个主题),如果主题的开始不为‘Re : ’,则在回复的时候,主题前面自动加上‘Re:’,最后就是html了,各自的标题及文本框,还有个提交按钮‘Save’,用于跳转到save.cgi,还有个链接 back to the main page,用以回到主页。

下面看 save.cgi代码:

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

import cgitb;cgitb.enable()

def quote(string):
        if string:
                return string.replace("'","\\'")
        else:
                return string

import MySQLdb
conn = MySQLdb.connect(db='hu',user='root')
curs = conn.cursor()

import cgi, 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')

if not (sender and subject and text):
        print 'Please supply sender,subject,text'
        sys.exit()

if reply_to is not None:
        query = """
        INSERT INTO messages

(reply_to,sender,subject,text)
        VALUES(%d,'%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>Messages Saved</title>
  </head>
  <body>
    <h1>Messages Saved</h1>
    <hr/>
    <a href='main.cgi'>Back to the main page</a>
  </body>
</html>s
'''

刚开始就定义一个quote函数,如果字符串存在,就把‘ ‘ ’换成’  \' ‘,否则返回本身。下面都是把获取到的值经过quote函数再赋给一个变量,而字段’reply_to‘就不需要,因为他是个整型,就直接获取了。下面意思是如果sender ,subject,text中有一个不存在(必须三个都存在才可以不执行下面的打印),就会打印需要你输入的信息,然后退出代码。

如果回复不为空,就往messages表中插入一条回复信息的记录,包括(reply_to,sender,subject,text),如果回复为空,就往messages表中插入一条不含有reply_to的记录,就是该条信息没人回复。commit()是把提交给数据库的信息更新。最后还是HTML,一个链接,back to the main page.


最后是 view.cgi:

print 'Content-type:text/html\n'
#import cgitb:cgitb.enable()
import MySQLdb
conn = MySQLdb.connect(db='hu',user='root')
curs = conn.cursor()

import cgi,sys
form = cgi.FieldStorage()
id = form.getvalue('id')

print """
<html>
    <head>
        <title>View Messages</title>
    </head>
    <body>
        <h1>View Messages</h1>
        """
try:
    id = int(id)
except:
    print 'Invalid messages ID'
    sys.exit()

curs.execute('SELECT * FROM messages WHERE id=%d'%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/>
<a href='main.cgi'>Back to the main page</a>
|<a href="edit.cgi?reply_to=%s">Reply</a>
</body>
</html>
''' % (row[1],row[2],row[4],row[0])

前面一样,不过这个获取上页传来的id的值,主要是用于显示id为某个值的那条记录,一个捕捉id类型的异常。然后是一个数据库查询,查找传过来的那个id的所有记录,如果没有记录则打印未知的id,最后是一个html,比较不同的是这个里面加了个、Reply的链接,用于回复信息跳转到edit.cgi页面。


0
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:28529次
    • 积分:575
    • 等级:
    • 排名:千里之外
    • 原创:28篇
    • 转载:6篇
    • 译文:0篇
    • 评论:11条
    文章分类
    最新评论