0
点赞
收藏
分享

微信扫一扫

CH-9 管理你的数据

念川LNSC 2022-10-11 阅读 43

1、生成HTML表单:

CH-9 管理你的数据_python

CH-9 管理你的数据_sqlite_02

test_form.py实现:

#! /usr/local/bin/python3

import yate

print(yate.start_response('text/html'))
print(yate.do_form('add_timing_data.py', ['TimeValue'], text="Send"))

View Code

yate.py实现:

from string import Template

def start_response(resp="text/html"):
return('Content-type: ' + resp + '\n\n')

def include_header(the_title):
with open('templates/header.html') as headf:
head_text = headf.read()
header = Template(head_text)
return(header.substitute(title=the_title))

def include_footer(the_links):
with open('templates/footer.html') as footf:
foot_text = footf.read()
link_string = ''
for key in the_links:
link_string += '<a href="' + the_links[key] + '">' + key + '</a>    '
footer = Template(foot_text)
return(footer.substitute(links=link_string))

def start_form(the_url, form_type="POST"):
return('<form action="' + the_url + '" method="' + form_type + '">')

def end_form(submit_msg="Submit"):
return('<p></p><input type=submit value="' + submit_msg + '">')

def radio_button(rb_name, rb_value):
return('<input type="radio" name="' + rb_name +
'" value="' + rb_value + '"> ' + rb_value + '<br />')

def radio_button_id(rb_name, rb_value, rb_id):
return('<input type="radio" name="' + rb_name +
'" value="' + str(rb_id) + '"> ' + rb_value + '<br />')

def u_list(items):
u_string = '<ul>'
for item in items:
u_string += '<li>' + item + '</li>'
u_string += '</ul>'
return(u_string)

def header(header_text, header_level=2):
return('<h' + str(header_level) + '>' + header_text +
'</h' + str(header_level) + '>')

def para(para_text):
return('<p>' + para_text + '</p>')

def create_inputs(inputs_list):
html_inputs = ''
for each_input in inputs_list:
html_inputs = html_inputs + '<input type="Text" name="' + each_input + '" size=40>'
return(html_inputs)

def do_form(name, the_inputs, method="POST", text="Submit"):
with open('templates/form.html') as formf:
form_text = formf.read()
inputs = create_inputs(the_inputs)
form = Template(form_text)
return(form.substitute(cgi_name=name,
http_method=method,
list_of_inputs=inputs,
submit_text=text))

View Code

form.html实现:

<form action="$cgi_name" method="$http_method">
Enter a timing value:
$list_of_inputs
<br />
<input type="Submit" value="$submit_text">
</form>

View Code

add_timing_data.py实现:表单数据传送到该CGI脚步

#! /usr/local/bin/python3

import cgi
import os
import time
import sys
import yate

print(yate.start_response('text/plain'))

addr = os.environ['REMOTE_ADDR']
host = os.environ['REMOTE_HOST']
method = os.environ['REQUEST_METHOD']
cur_time = time.asctime(time.localtime())
print(host + ", " + addr + ", " + cur_time + ": " + method + ": ",
end='', file=sys.stderr)

form = cgi.FieldStorage()
for each_form_item in form.keys():
print(each_form_item + '->' + form[each_form_item].value,
end=' ', file=sys.stderr)
print(file=sys.stderr)

print('OK.')

View Code

CH-9 管理你的数据_python_03

CH-9 管理你的数据_sqlite_04

CH-9 管理你的数据_html_05

CH-9 管理你的数据_python_06

CH-9 管理你的数据_python_07

 

以上实现了一个简单的数据输入表单,并且输入到表单的数据确实已经传送到服务器上的CGI脚本。

 

2、利用数据库

python 的数据库API:

CH-9 管理你的数据_html_08

数据库API的相应Python代码:

import sqlite3

connection = sqlite3.connect('coachdata.sqlite')

cursor = connection.cursor()
cursor.execute("""SELECT DATA('NOW')""")
connection.commit()
connection.close()

CH-9 管理你的数据_html_09

CH-9 管理你的数据_html_10

createDBtables.py实现:  创建coachdata.sqlite数据库,包含空的athletes和timing_data两个表

import os
import sqlite3

connection = sqlite3.connect('coachdata.sqlite')

cursor = connection.cursor()
cursor.execute("""CREATE TABLE athletes (
id INTEGER PRIMARY KEY AUTOINCREMENT UNIQUE NOT NULL,
name TEXT NOT NULL,
dob DATE NOT NULL )""")
cursor.execute("""CREATE TABLE timing_data (
athlete_id INTEGER NOT NULL,
value TEXT NOT NULL,
FOREIGN KEY (athlete_id) REFERENCES athletes)""")

connection.commit()
connection.close()

View Code

从pickle向SQLite传输数据:

initDBtables.py实现:它从现有模型的pickle中取得选手的数据,并将数据加载到新创建的SQLite数据库表中

import sqlite3

connection = sqlite3.connect('coachdata.sqlite')
cursor = connection.cursor()

import glob
import athletemodel

data_files = glob.glob("../data/*.txt")
athletes = athletemodel.put_to_store(data_files)

for each_ath in athletes:
name = athletes[each_ath].name
dob = athletes[each_ath].dob
cursor.execute("INSERT INTO athletes (name, dob) VALUES (?, ?)", (name, dob))
connection.commit()
cursor.execute("SELECT id from athletes WHERE name=? AND dob=?", (name, dob))
the_current_id = cursor.fetchone()[0]
for each_time in athletes[each_ath].clean_data:
cursor.execute("INSERT INTO timing_data (athlete_id, value) VALUES (?, ?)",
(the_current_id, each_time))
connection.commit()

connection.close()

View Code

athletemodel.py实现:

import pickle

from athletelist import AthleteList

def get_coach_data(filename):
try:
with open(filename) as f:
data = f.readline()
templ = data.strip().split(',')
return(AthleteList(templ.pop(0), templ.pop(0), templ))
except IOError as ioerr:
print('File error (get_coach_data): ' + str(ioerr))
return(None)

def put_to_store(files_list):
all_athletes = {}
for each_file in files_list:
ath = get_coach_data(each_file)
all_athletes[ath.name] = ath
try:
with open('athletes.pickle', 'wb') as athf:
pickle.dump(all_athletes, athf)
except IOError as ioerr:
print('File error (put_and_store): ' + str(ioerr))
return(all_athletes)

def get_from_store():
all_athletes = {}
try:
with open('athletes.pickle', 'rb') as athf:
all_athletes = pickle.load(athf)
except IOError as ioerr:
print('File error (get_from_store): ' + str(ioerr))
return(all_athletes)

View Code

athletelist.py实现:

class AthleteList(list):

def __init__(self, a_name, a_dob=None, a_times=[]):
list.__init__([])
self.name = a_name
self.dob = a_dob
self.extend(a_times)

@staticmethod
def sanitize(time_string):
if '-' in time_string:
splitter = '-'
elif ':' in time_string:
splitter = ':'
else:
return(time_string)
(mins, secs) = time_string.split(splitter)
return(mins + '.' + secs)

@property
def top3(self):
return(sorted(set([self.sanitize(t) for t in self]))[0:3])

@property
def clean_data(self):
return(sorted(set([self.sanitize(t) for t in self])))

@property
def as_dict(self):
return({'Name': self.name,
'DOB': self.dob,
'Top3': self.top3})

View Code

CH-9 管理你的数据_python_11

CH-9 管理你的数据_sqlite_12

SQLite 数据管理工具:SQLite Manager  详见本网站随笔"​​SQLite Manager插件安装与使用(firefox)​​"

CH-9 管理你的数据_html_13

SQLite 与现有的WEB应用(详见CH7-WEB开发章节)集成:

现在要使用SQLite,而不是pickle。

首先修改athletemodel.py模块代码:  修改原来的模型

import sqlite3

db_name = 'coachdata.sqlite'

#获得选手名字列表
def get_names_from_store():
connection = sqlite3.connect(db_name)
cursor = connection.cursor()
results = cursor.execute("""SELECT name FROM athletes""")
response = [row[0] for row in results.fetchall()]
connection.close()
return(response)

#根据ID获得选手的详细信息
def get_athlete_from_id(athlete_id):
connection = sqlite3.connect(db_name)
cursor = connection.cursor()
results = cursor.execute("""SELECT name, dob FROM athletes WHERE id=?""",
(athlete_id,))
(name, dob) = results.fetchone()
results = cursor.execute("""SELECT value FROM timing_data WHERE athlete_id=?""",
(athlete_id,))
data = [row[0] for row in results.fetchall()]
response = {'Name': name,
'DOB': dob,
'data': data,
'top3': data[0:3]}
connection.close()
return(response)

#获取选手名和ID
def get_namesID_from_store():
connection = sqlite3.connect(db_name)
cursor = connection.cursor()
results = cursor.execute("""SELECT name, id FROM athletes""")
response = results.fetchall()
connection.close()
return(response)

View Code

模型转换成功!

现在修改各个CGI脚本来使用这个新的模型API:

generate_list.py修改为:

#! /usr/local/bin/python3

import athletemodel
import yate

athletes = athletemodel.get_namesID_from_store()

print(yate.start_response())
print(yate.include_header("The NUAC's List of Athletes"))
print(yate.start_form("generate_timing_data.py"))
print(yate.para("Select an athlete from the list to work with:"))
for each_athlete in sorted(athletes):
print(yate.radio_button_id("which_athlete", each_athlete[0], each_athlete[1]))
print(yate.end_form("Select"))
print(yate.include_footer({"Home": "/index.html"}))

View Code

generate_timing_data.py修改为:

#! /usr/local/bin/python3

import cgi
import athletemodel
import yate

form_data = cgi.FieldStorage()
athlete_id = form_data['which_athlete'].value
athlete = athletemodel.get_athlete_from_id(athlete_id)

print(yate.start_response())
print(yate.include_header("NUAC's Timing Data"))
print(yate.header("Athlete: " + athlete['Name'] + ", DOB: " + athlete['DOB'] + "."))
print(yate.para("The top times for this athlete are:"))
print(yate.u_list(athlete['top3']))
print(yate.para("The entire set of timing data is: " + str(athlete['data']) +
" (duplicates removed)."))
print(yate.include_footer({"Home": "/index.html", "Select another athlete": "generate_list.py"}))

View Code

将SQLite数据库移至WEB应用的顶层目录(index.html所在目录),

CH-9 管理你的数据_html_14

CH-9 管理你的数据_python_15

CH-9 管理你的数据_sqlite_16

index.html实现:

<html>
<head>
<title>Welcome to the National Underage Athetics Committee's Website</title>
<link type="text/css" rel="stylesheet" href="coach.css" />
</head>
<body>
<img src="images/nuac-group.jpg">
<h1>Welcome to the NUAC's Website.</h1>
<p>
Here is our athlete's <a href="cgi-bin/generate_list.py">timing data</a>. Enjoy!
</p>
<p>
<strong>See you on the track!</strong>
</p>
</body>
</html>

View Code

CH-9 管理你的数据_python_17

CH-9 管理你的数据_python_18

CH-9 管理你的数据_python_19

CH-9 管理你的数据_html_20

一切正常!!!

更新SQLite中的选手数据:

修改add_timing_data.py CGI脚本,将你提交的数据写至数据库,而不是写到WEB服务器的控制台屏幕

add_timing_data.py修改为:

#! /usr/local/bin/python3

import cgi
import sqlite3

import yate

print(yate.start_response('text/plain'))

form = cgi.FieldStorage()
the_id = form['Athlete'].value
the_time = form['Time'].value

connection = sqlite3.connect('coachdata.sqlite')
cursor = connection.cursor()
cursor.execute("INSERT INTO timing_data (athlete_id, value) VALUES (?, ?)",
(the_id, the_time))
connection.commit()
connection.close()

print('OK.')

View Code

test_form.py修改为:

#! /usr/local/bin/python3

import yate

print(yate.start_response('text/html'))
print(yate.do_form('add_timing_data.py', ['Athlete','Time'], text="Send"))

View Code

yate.py保持不变:

from string import Template

def start_response(resp="text/html"):
return('Content-type: ' + resp + '\n\n')

def include_header(the_title):
with open('templates/header.html') as headf:
head_text = headf.read()
header = Template(head_text)
return(header.substitute(title=the_title))

def include_footer(the_links):
with open('templates/footer.html') as footf:
foot_text = footf.read()
link_string = ''
for key in the_links:
link_string += '<a href="' + the_links[key] + '">' + key + '</a>    '
footer = Template(foot_text)
return(footer.substitute(links=link_string))

def start_form(the_url, form_type="POST"):
return('<form action="' + the_url + '" method="' + form_type + '">')

def end_form(submit_msg="Submit"):
return('<p></p><input type=submit value="' + submit_msg + '">')

def radio_button(rb_name, rb_value):
return('<input type="radio" name="' + rb_name +
'" value="' + rb_value + '"> ' + rb_value + '<br />')

def radio_button_id(rb_name, rb_value, rb_id):
return('<input type="radio" name="' + rb_name +
'" value="' + str(rb_id) + '"> ' + rb_value + '<br />')

def u_list(items):
u_string = '<ul>'
for item in items:
u_string += '<li>' + item + '</li>'
u_string += '</ul>'
return(u_string)

def header(header_text, header_level=2):
return('<h' + str(header_level) + '>' + header_text +
'</h' + str(header_level) + '>')

def para(para_text):
return('<p>' + para_text + '</p>')

def create_inputs(inputs_list):
html_inputs = ''
for each_input in inputs_list:
html_inputs = html_inputs + '<input type="Text" name="' + each_input + '" size=40>'
return(html_inputs)

def do_form(name, the_inputs, method="POST", text="Submit"):
with open('templates/form.html') as formf:
form_text = formf.read()
inputs = create_inputs(the_inputs)
form = Template(form_text)
return(form.substitute(cgi_name=name,
http_method=method,
list_of_inputs=inputs,
submit_text=text))

View Code

启动WEB服务器:

CH-9 管理你的数据_python_21

CH-9 管理你的数据_html_22

CH-9 管理你的数据_python_23

CH-9 管理你的数据_html_24

 

数据成功插入数据库!!!

 



举报

相关推荐

0 条评论