使用python3的http.server模块要注意的问题

在学习python的web开发时,首先使用了python3中内建的HTTP servers。

使用如下代码:

from http.server import HTTPServer, CGIHTTPRequestHandler

port = 8080

httpd = HTTPServer(('', port), CGIHTTPRequestHandler)
print("Starting simple_httpd on port: " + str(httpd.server_port))
httpd.serve_forever()

创建一个web服务器文件simple_httpd.py,在终端上运行该文件:

在浏览器的地址栏输入 http://localhost:8080,可打文件simplehttpd.py所在文件夹里的index.html页面。

这样就可以对index.html作个性化设计,来实际操练基于python的CGI脚本的web开发了。


背景:一个教练带着一群跑步运动员训练,并为每一个选手每一次测试时间进行记录,教练想要一种很方便的方式来管理这些测试数据,譬如需要查看每个选手跑得最快的3次记录,查看指定选手的所有测试记录,为选手添加新的记录等功能。


方案:为教练设计一个webapp,该web应用遵循MVC模式。

我们将顶层文件夹命名为mrdw

下面包含cgi-bin、data、images、templates等子文件夹,还包括index.html、CSS样式表等不适合放在前面子文件夹中的其他文件。

特别命名的cgi-bin文件夹用来放为web应用所写的代码文件;

data文件夹用来放测试的数据文件;

images文件夹用来放web应用相关的图片文件;

templates文件夹用来HTML网页模板。


为了支持更多更灵活的功能,需要使用database management system(数据库管理系统)来支持web应用的数据管理。我们采用轻量级的SQLite作为web应用的数据库,导入python的内建模块sqlite3后,就可以使用python的标准化数据库API来编程。


现在来实现为现有选手增加新的测试记录这一功能,

重写模板form.html文件和脚本test_form.py,效果如下:

在这个HTML表单里填入选手的id和新的时间数据,然后点击Send按钮就可以将数据发送到web server,并指定脚本add_timing_data.py来处理,将新的数据存储到数据库文件coachdata.sqlite里。

为了确保存入数据里的数据的正确性,我们应该对发送过来的数据做有效性检查。

于是我们在athletemodel.py模块里面定义一个函数check_athleteId(athlete_id)来检查athlete_id是存在于数据库里。

第一个版本:

def check_athleteId(athlete_id):
	connection = sqlite3.connect('coachdata.sqlite')
	cursor = connection.cursor()
	results = cursor.execute("""SELECT id FROM athletes""")
	id_list = [row[0] for row in results.fetchall()]
	connection.close()
	print('id_list is ', id_list)
	for each in id_list:
		if each == athlete_id:
			return (True)
		else:
			continue
	return (False)
在server上被文件add_timing_data.py调用时执行出错:


但是在python3.4.2 解释器环境下运行正确:



然后第二个版本:

def check_athleteId(athlete_id):
	connection = sqlite3.connect('coachdata.sqlite')
	cursor = connection.cursor()
	results = cursor.execute("""SELECT id FROM athletes""")
	id_list = [row[0] for row in results.fetchall()]
	connection.close()
	print('id_list is ', id_list)
	if athlete_id in id_list:
		return (True)
	else:
		return (False)
还是出错:


同样在python3.4.2 解释器环境下运行正确:


再尝试第三个测试版本:

def check_athleteId(athlete_id):
	connection = sqlite3.connect('coachdata.sqlite')
	cursor = connection.cursor()
	results = cursor.execute("""SELECT id FROM athletes""")
	id_list = [row[0] for row in results.fetchall()]
	connection.close()
	print('id_list is ', id_list)
	idx = id_list.index(athlete_id)
	print(idx)
	return (idx)
还是出错:


同样在python3.4.2 解释器环境下运行正确:


以上测试在32位的windows系统和ubuntu系统全都测试过,表现一样。
最后采用第四版,代码参见:https://github.com/robot527/python_primer/blob/master/mrdw/cgi-bin/athletemodel.py
终于达到了预想的效果。


后来与同事讨论后,发现了问题所在,

原因在于add_timing_data.py文件里,

new_data = {}
for key in form.keys():
	new_data[key] = form[key].value
the_id = new_data['Athlete_id']
the_time = new_data['Time']

if check_athleteId(the_id):
 

处理后这个变量the_id是一个字符串,作为参数传入函数check_athleteId里,执行结果与预想的不一致,所以出现了上述所谓的错误!

所以使用前面三个版本的检查函数时,都应该将 if check_athleteId(the_id): 修改为 if check_athleteId(int(the_id)):

学习和实践过程中难免会碰到一些短时间难以解释的问题,这时就需要我们冷静,多思考各种细节问题,还要多动手尝试,相信最终总会找到解决问题提的办法的微笑

Ps:那么新问题又来了,为什么第四版

def check_athleteId(athlete_id):
	connection = sqlite3.connect(db_name)
	cursor = connection.cursor()
	results = cursor.execute("""SELECT name FROM athletes WHERE id = ?""", (athlete_id,))
	sel_data = results.fetchall()
	connection.close()
	if sel_data == []:
		return (False)
	else:
		return (True)
对于输入参数athlete_id为字符串或者整数时都可以正常工作?



版权声明:本文版权属于若要走,并受法律保护。

本文授权方式采用 Creative Commons「署名 - 非商业性使用 - 禁止演绎 4.0」许可协议。

接受自由转载,但必须署名、注明来源,且禁止用于商业用途。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值