python项目七:自建公告板

项目来自python 基础教程的项目七
项目介绍
这个项目使用 python cgi结合MySQL完成了一个类似公告板功能的web应用
项目的再次实现
项目的再次实现将程序分为四个部分:
main.py:相当于主页,实现的功能有:层次的显示所有消息的主题,将主题的内容链接到view.pu,传递主题的id
viem.py:根据cgi传递的id显示主题的内容,链接到edit.py;传递本条消息的id转为回复内容的reply_to
edit.py:编辑输入窗口,输入后将内容传递给save.py保存到数据库
save.py:接收内容,写入数据库

cgi:通用网关接口,是python运行web服务器交换数据的;web服务器通过它将查询提供给程序(自己写的python),再通过网页的形式显示。cgi脚本的输入通常使用表单;也可以使用类似?&id = 2的方式。
使用cgi;
第一步:建立web服务器:python -m http.server --cgi
第二步:# !/usr/bin/python 告诉服务器python解析
第三步:编写cgi程序 如下

main.py

# !/usr/bin/python

print("Content-Type:text/html\n")

import pymysql
import cgitb;cgitb.enable()#调试模块,错误可以打印在网页上
"""
此为主页面;主要功能有二
按照結構展示主題和回復結構
链接到view.py显示每一条消息的内容
"""
ip = '127.0.0.1'
db = 'billbord'
user = 'root'
port = 3308
passwrd  = 'PSPS2053'
conn = pymysql.connect(host =ip,db = db,user = user,port = port,passwd=passwrd)
curs = conn.cursor(cursor=pymysql.cursors.DictCursor) #设置返回内容为字典的形式

print("""
<html>
  <head>
    <title>The FooBar Bulletin Board</title>
  </head>
  <body>
    <h1>The FooBar Bulletin Board</h1>
    """)

curs.execute('SELECT * FROM message')
# rows = curs.dictfetchall() mymysql不支持dictfetchall(),pymysql是在游标设置的
rows = curs.fetchall()

toplevel = []
children = {}

#根据reply_to判断是否为回复的消息,如果不是回复,则为顶层消息;如果是恢复,确定其层级
for row in rows:
    parent_id = row['reply_to']
    if parent_id is None:
        toplevel.append(row)
    else:
        children.setdefault(parent_id, []).append(row) #如果键不存在则插入值为默认值的键,就是有就插入没有就创建
        #如果是回复的消息,则添加到children字典中
def format(row):
    """此方法实现了对消息和回复的显示,如果有回复消息,则递归调用显示"""
    print('<p><a href="view.py?id={id}">{subject}</a></p>'.format(id = row['id'],subject = row['subject']))
    #以链接的形式返回主题,并且链接到view.py,get的方式,以键值对的形式传递参数
    try: kids = children[row['id']] #是否有回复消息,如果有,则递归调用回复消息,打印引用消息
    except KeyError: pass
    else:
        print('<blockquote>')
        for kid in kids:
            format(kid)
        print('</blockquote>')

print("""<p>""")

for row in toplevel:
    format(row)

print("""
</p>
</body>
</html>
""")

view.py

#!/usr/bin/python

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

import cgitb; cgitb.enable()
"""
根据传入的ID在数据库查询信息以html方式显示内容此条内容的信息
跳转的链接,跳转到回复编辑的界面
"""
import pymysql
ip = '127.0.0.1'
db = 'billbord'
user = 'root'
port = 3308
passwrd  = 'PSPS2053'
conn = pymysql.connect(host =ip,db = db,user = user,port = port,passwd=passwrd)
curs = conn.cursor(cursor=pymysql.cursors.DictCursor) #设置返回内容为字典的形式

import cgi, sys
form = cgi.FieldStorage()
id = form.getvalue('id') #获取cgi传递的参数

print("""
<html>
  <head>
    <title>View Message</title>
  </head>
  <body>
    <h1>View Message</h1>
    """)

try: id = int(id)
except:
     print('Invalid message ID')
     sys.exit()

curs.execute('SELECT * FROM message WHERE id = %s', (format(id),))
rows = curs.fetchall()

if not rows:
     print('Unknown message ID')
     sys.exit()

row = rows[0]

print("""
     <p><b>Subject:</b> {subject}<br />
     <b>Sender:</b> {sender}<br />
     <pre>{text}</pre>
     </p>
     <hr />
     <a href='main.py'>Back to the main page</a>  <!--返回主页的方式-->
     | <a href="edit.py?reply_to={id}">Reply</a>  <!--跳转到编辑界面的链接-->
  </body>
</html>
""".format(subject=row['subject'],sender=row['sender'],text=row['text'],id=row['id']))

edit.py

#!/usr/bin/python

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

import cgitb; cgitb.enable()

import pymysql
ip = '127.0.0.1'
db = 'billbord'
user = 'root'
port = 3308
passwrd  = 'PSPS2053'
conn = pymysql.connect(host =ip,db = db,user = user,port = port,passwd=passwrd)
curs = conn.cursor(cursor=pymysql.cursors.DictCursor) #设置返回内容为字典的形式
"""
实现了回复功能;接收传递过来的id,作为replay_to编号
"""
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.py' method='POST'> <!--声明使用post方法传递数据,通过表单的形式-->
    """)

subject = ''
if reply_to is not None:
    print('<input type="hidden" name="reply_to" value="{}"/>'.format(reply_to))
    curs.execute('SELECT subject FROM message WHERE id = %s', (format(reply_to),))
    subject = curs.fetchone()['subject'] #返回查询到的subject的主题
    if not subject.startswith('Re: '):
        subject = 'Re: ' + subject
"""
以html的格式展示回复数据;包括回复主题;回复人;回复内容
提供保存链接
"""
print("""
     <b>Subject:</b><br />
     <input type='text' size='40' name='subject' value='{}' /><br /> <!--br为html的换行元素-->
     <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.py'>Back to the main page</a>
  </body>
</html>
""".format(subject))

save.py

#!/usr/bin/python

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

import cgitb; cgitb.enable()

import pymysql
ip = '127.0.0.1'
db = 'billbord'
user = 'root'
port = 3308
passwrd  = 'PSPS2053'
conn = pymysql.connect(host =ip,db = db,user = user,port = port,passwd=passwrd)
curs = conn.cursor(cursor=pymysql.cursors.DictCursor) #设置返回内容为字典的形式
"""
实现了数据保存
通过cgi传递过来的数据:reply_to,sender,text,subject数据插入数据库;
"""
import cgi, sys
form = cgi.FieldStorage()

sender = form.getvalue('sender')
subject = form.getvalue('subject')
text = form.getvalue('text')
reply_to = form.getvalue('reply_to')

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

if reply_to is not None:
    query = ("""INSERT INTO message(reply_to, sender, subject, text) VALUES(%s, %s, %s, %s)""",
             (int(reply_to), sender, subject, text))
else:
    query = ("""INSERT INTO message(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.py'>Back to the main page</a>
</body>
</html>s
""")
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值