Python之基于web的shelve界面

代码文件的介绍

  • .html文件为输入表单,实现界面交互的功能,以及显示的获得结果和处理更新请求的python CGI脚本。
  • .py文件用来查看和更新保存在shelve类中类实例的基于Web的界面,存储在cgi-bin文件夹之内,cgi-bin
    文件夹应与.html文件在同一目录下
  • class-shelve文件为类似数据库的文件,存储了大量人员的信息,很像一直打开的字典,操作数据简便。
    该文件与.html文件在同一目录下

编码实现网站

  • peoplecgi.html

      <html>
      <title>People Input From</title>
      <body>
      <form method=Post action="http://localhost:8081/cgi-bin/peoplecgi.py">
          <table>
              <tr><th>Key <td><input type=text name=key>
              <tr><th>Name<td><input type=text name=name>
              <tr><th>Age <td><input type=text name=age>
              <tr><th>Job <td><input type=text name=job>
              <tr><th>Pay <td><input type=text name=pay>
          </table>
          <p>
          <input type=submit value="Fetch", name=action>
          <input type=submit value="Update", name=action>
      </form>
      </body>
      </html>
    

    action: 提供返回处理下一个脚本的请求连接
    提交表单展示:
    在这里插入图片描述

脚本实现

  • 主html模板

      # 主html模板
      replyhtml = """
      <html>
      <title>People Input Form</title>
      <body>
      <form method=POST action="http://localhost:8081/peoplecgi.py">
          <table>
          <tr><th>Key<td><input type=text name=key value="%(key)s">
          $ROWS$
          </table>
          <p>
          <input type=submit value="Fetch", name=action>
          <input type=submit value="Update", name=action>
      </form>
      </body></html>
      """
      # 为$ROWS$的数据行插入html
      # rowhtml提供了当前查询的属性
      rowhtml = '<tr><th>%s<td><input type=text name=%s value="%%(%s)s">\n'
      rowshtml = ''
      for fieldname in fieldnames:
          # 这种方式用符号“%”连接一个字符串和一组变量,字符串中的特殊标记会被自动用右边变量组中的变量替换
          # 使用字符串格式化将来自于记录的属性字典的键值填充到这段文本中
          rowshtml += (rowhtml % ((fieldname,)*3))
      # 在replyhtml代码中的$ROWS$中替换为rowshtml
      replyhtml = replyhtml.replace('$ROWS$', rowshtml)
    

这段代码实现了对网页提交的表单进行解析处理并提供一个网页来展现查询的结果

  • 通过key查询数据库的内容

      def fetchRecord(db, form):
          try:
              # 找到form表单中待查找的'key'键
              key = form['key'].value
              # 将该‘key'记录下来
              record = db[key]
              fields = record.__dict__                # 使用属性字典,fields是字典类的属性字典
              fields['key'] = key                     # 填充响应字符, 将表单中key的value赋给属性字典的key属性
          except:
              # 新建一个字典,键为fieldnames,值都默认为'?'
              fileds = dict.fromkeys(fieldnames, '?')
              fields['key'] = 'Missing or invalid key!'
          return fields
    

实现查找功能,db为数据库字典, form是解析后的完整的表单,返回有着key中的工作人员的所有信息

  • 更新数据库中的数据(添加和修改)

      def updateRecord(db, form):
          # 如果表单中没有key属性
          if not 'key' in form:
              fields = dict.fromkeys(fieldnames, '?')
              fields['key'] = 'Missing key input!'
          # 如果存在key属性
          else:
              # 从表单中得到key
              key = form['key'].value
              # 在数据库中查询该人员,若有直接添加到查询记录中
              if key in db:
                  record = db[key]
              # 如果没有该人员就直接创建对象,并直接将对象送往人员字典信息中
              else:
                  from person import Person
                  record = Person(name='?', age='?')
                  for field in fieldnames:
                      setattr(record, field, eval(form[field].value))
              # 将从html中得到的新的用户信息存入数据局中得到更新
              db[key] = record
              fields = record.__dict__
              fields['key'] = key
          return fields
    

更新数据库中的内容,所传参数为db数据库和解析后的表单form,返回key的工作人员的消息

  • 转义在功能函数中得到的数据库中的查询记录

      def htmlize(adict):
          new = adict.copy()
          for field in fieldnames:                     # 值可能包含&, >等字符
              value = new[field]                      # 作为代码显示: 被引号引起
              # 通过repr将字典的值转换为代码文本
              new[field] = html.escape(repr(value))    # 转义HTML字符
          return new
    
  • 主函数部分

      	# db中存储class-shelve数据库中的数据集
      	db = shelve.open(shelvename)
      	# action规定了向何处发送表单数据,它的值是一个URL
      	# form中得到的是一个结果后的表单,如果在改表单中能找到'action'就获取它的action值value见replyhtml代码,否则什么也不干
      	action = form['action'].value if 'action' in form else None
      	# 判断action的value值,调用相应的函数
      	if action == 'Fetch':
      	    fields = fetchRecord(db, form)
      	elif action == 'Update':
      	    fields = updateRecord(db, form)
      	else:
      	    # 用于创建并返回一个新的字典。两个参数:第一个是字典的键,第二个(可选)是传入键的值,默认为None。
      	    fields = dict.fromkeys(fieldnames, '?')
      	    fields['key'] = 'Missing or invalid actoin'
      	db.close()
      	print(replyhtml % htmlize(fields))
    
  • 对代码中的一些变量的介绍

      shelvename:		 	shelve文件的名字(查找路径)
      fieldnames: 			数据库中存储的各个人员的属性名
      replyhtml:			结果展示的网页代码
      rowshtml:				网页的一部分代码,用来构建人员各个属性的表单替换网页源码中的$ROWS$
      key:					shelve数据库中的键
      record:				更新数据库功能中,暂存新人员信息记录
      fields:				获得了最终想要查询(修改\添加)的某人员的信息
      db:					shelve数据库(可以理解为一个字典的字典)
    

完整的py文件

"""
    实现用来查看和更新保存在shelve中类实例的基于web的界面;
    shelve保存在服务器上(如果是本地机器德华,就是同一个机器)
"""

import cgi, shelve, sys, os           # cgi.test()转储输入
import html	
shelvename = 'class-shelve'
fieldnames = ('name', 'age', 'job', 'pay')


# form['file']或form[ ' trial ' ]表示一个input标签整体,而标签有属性,如可以通过form['file'].filename或form['file'].file等来获取文件的相关信息,
# 通过form[ ' trial ' ].value来获取text文本框里面的值。
# form是fieldStorage()的实例,代表着解析后的整个前端发来的表单
form = cgi.FieldStorage()               # 解析表单数据
print('Content-type: text/html')        # 响应html中的hdr和空行
# sys.path.insert定义搜索路径的优先顺序,序号从0开始,表示最大优先级,sys.path.insert()加入的是临时搜索路径,程序退出后失效。
# os.getcwd()用于获取当前执行python文件的文件夹,但是返回的是当前python被执行的文件夹,而不是文件所在文件夹
# 也就是说在本程序在上一级的文件中调用,返回的是html文件所在的文件夹,而不是该py文件所在的文件夹,切记
# 总体来说是为了查找当前文件和Person
sys.path.insert(0, os.getcwd())


# 主html模板,提供对key的操作Fetch或者Update
replyhtml = """
    <html>
    <title>People Input Form</title>
    <body>
    <form method=POST action="http://localhost:8081/peoplecgi.py">
        <table>
        <tr><th>Key<td><input type=text name=key value="%(key)s">
        $ROWS$
        </table>
        <p>
        <input type=submit value="Fetch", name=action>
        <input type=submit value="Update", name=action>
    </form>
    </body></html>
"""


# 为$ROWS$的数据行插入html
# rowhtml提供了当前查询的
rowhtml = '<tr><th>%s<td><input type=text name=%s value="%%(%s)s">\n'
rowshtml = ''
for fieldname in fieldnames:
    # 这种方式用符号“%”连接一个字符串和一组变量,字符串中的特殊标记会被自动用右边变量组中的变量替换
    # 使用字符串格式化将来自于记录的属性字典的键值填充到这段文本中
    rowshtml += (rowhtml % ((fieldname,)*3))
# 在replyhtml代码中的$ROWS$中替换为rowshtml
replyhtml = replyhtml.replace('$ROWS$', rowshtml)


# 将字典中的个属性的值转义为HTML字符
def htmlize(adict):
    new = adict.copy()
    for field in fieldnames:                     # 值可能包含&, >等字符
        value = new[field]                      # 作为代码显示: 被引号引起
        # 通过repr将字典的值转换为代码文本
        new[field] = html.escape(repr(value))    # 转义HTML字符
    return new


# 实现查找功能,db为数据库字典, form是解析后的完整的表单,返回有着key中的工作人员的所有信息
def fetchRecord(db, form):
    try:
        # 找到form表单中待查找的'key'键
        key = form['key'].value
        # 将该‘key'记录下来
        record = db[key]
        fields = record.__dict__                # 使用属性字典,fields是字典类的属性字典
        fields['key'] = key                     # 填充响应字符, 将表单中key的value赋给属性字典的key属性
    except:
        # 新建一个字典,键为fieldnames,值都默认为'?'
        fileds = dict.fromkeys(fieldnames, '?')
        fields['key'] = 'Missing or invalid key!'
    return fields


# 更新数据库中的内容,所传参数为db数据库和解析后的表单form,返回key的工作人员的消息
def updateRecord(db, form):
    # 如果表单中没有key属性
    if not 'key' in form:
        fields = dict.fromkeys(fieldnames, '?')
        fields['key'] = 'Missing key input!'
    # 如果存在key属性
    else:
        # 从表单中得到key
        key = form['key'].value
        # 在数据库中查询该人员,若有直接添加到查询记录中
        if key in db:
            record = db[key]
        # 如果没有该人员就直接创建对象,并直接将对象送往人员字典信息中
        else:
            from person import Person
            record = Person(name='?', age='?')
            for field in fieldnames:
                setattr(record, field, eval(form[field].value))
        # 将从html中得到的新的用户信息存入数据局中得到更新
        db[key] = record
        fields = record.__dict__
        fields['key'] = key
    return fields


# db中存储class-shelve数据库中的数据集
db = shelve.open(shelvename)
# action规定了向何处发送表单数据,它的值是一个URL
# form中得到的是一个结果后的表单,如果在改表单中能找到'action'就获取它的action值value见replyhtml代码,否则什么也不干
action = form['action'].value if 'action' in form else None
# 判断action的value值,调用相应的函数
if action == 'Fetch':
    fields = fetchRecord(db, form)
elif action == 'Update':
    fields = updateRecord(db, form)
else:
    # 用于创建并返回一个新的字典。两个参数:第一个是字典的键,第二个(可选)是传入键的值,默认为None。
    fields = dict.fromkeys(fieldnames, '?')
    fields['key'] = 'Missing or invalid actoin'
db.close()
print(replyhtml % htmlize(fields))

效果

  • 查询bob的信息

在这里插入图片描述
在这里插入图片描述

  • 增加人员信息
    在这里插入图片描述
    我们重新打开网页fetch一下dijia

在这里插入图片描述
我们可以看到自己能成功地查看到上一次输入的内容,说明dijia已经在我们的数据库之中了
在这里插入图片描述

CGI无法提交表单,或得不到响应

见:https://blog.csdn.net/qq_44859600/article/details/102489718

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值