今日完成:修改login前后台,修改exam前后台、做题记录存到数据库
1、exam.html(其中的css可以拿出去放到static中)
<html><head><title>在线考试title><script src="{{ url_for('static',filename='jquery.js') }}">script><script type="text/javascript">$(function () {$("#btn").click(function(){data = $('#fm').serialize();$.post("exam",data,function(txt){if(txt=="nolog"){alert("对不起,请先登录!");window.location.href='/login';}else if(txt!="dup"){alert(txt);}else{alert("抱歉,您已经交卷,不能重复提交!")}})});});script><style type="text/css">body{margin:0;padding:0}#header{height:50px;background:#00E3E3;}#logo{font-size:24px;float:left;width:200px;margin-top:10px;margin-left:10px;color:#FF5809;font-weight:bold;}#who{float:right;width:200px;margin-top:15px;}#content{padding-left:30px;}ul li {list-style:none;margin:5 0;font-size:14px;}#btn{width:120px;height:30px;}style>head><body><div id="header"><div id="logo">信息技术随堂测验div><div id="who">当前登录用户:{{who}}div>div><div id="content"><form id="fm" onsubmit="return false" action="##" method="post" ><p>1、关于线性链表的描述,以下选项中正确的是( )p><ul><li><input name="q_1" type="radio" value="A"/>A.存储空间不一定连续,且各元素的存储顺序是任意的li><li><input name="q_1" type="radio" value="B"/>B.存储空间必须连续,且各元素的存储顺序是任意的li><li><input name="q_1" type="radio" value="C"/>C.存储空间不一定连续,且前件元素一定存储在后件元素的前面li><li><input name="q_1" type="radio" value="D"/>D.存储空间必须连续,且前件元素一定存储在后件元素的前面li>ul><p>2、关于 Python 程序格式框架的描述,以下选项中错误的是 ( )p><ul><li><input name="q_2" type="radio" value="A"/>A.Python 语言不采用严格的“缩进”来表明程序的格式框架li><li><input name="q_2" type="radio" value="B"/>B.Python 单层缩进代码属于之前最邻近的一行非缩进代码,多层缩进代码根据缩进关系决定所属范围li><li><input name="q_2" type="radio" value="C"/>C.Python 语言的缩进可以采用 Tab 键实现li><li><input name="q_2" type="radio" value="D"/>D.判断、循环、函数等语法形式能够通过缩进包含一批 Python 代码,进而表达对应的语义li>ul><input type="button" value="提交" id="btn">form>div>body>html>
2、login.html(增加登录成功提示、跳转功能)
<html lang="en"><head> <meta charset="UTF-8"> <title>学生登录页面title><script src="/static/jquery.js">script><script type="text/javascript">$(function () {$("#btn").click(function(){data = $('#fm').serialize();$.post("login",data,function(txt){if(txt=='suc'){alert("登录成功!");window.location.href='/exam';}else{alert("登录失败!请检查学号是否存在,密码是否正确!")}})});});script>head><body> <h2>请用学号登录网站h2> <form id="fm" onsubmit="return false" action="##" method="post"> <table> <tr> <td>学号:td> <td><input type="text" name='username' >td> tr> <tr> <td>密码:td> <td><input type="password" name='password' >td> tr> <tr> <td><input type="submit" value="登陆" id="btn">td> tr> table> form>body>html>
3、对应的后台修改(增加Session记录用户状态、数据库操作)
from flask import Flask,render_template,request,jsonify,redirect,sessionfrom werkzeug.utils import secure_filenameimport osimport xlrdimport excel2dbimport sqlite3app = Flask(__name__)app.config['SECRET_KEY']=os.urandom(24)answers={1:'B',2:'C'}@app.route('/exam',methods = ['POST', 'GET'])def exam(): un=session.get('sid') count=0 if request.method == 'POST': if un==None: return "nolog" else: con = sqlite3.connect("./DB/stuScores.db") cur = con.cursor() result = request.form cur.execute("select * from 考试记录 where 学号='%s'" % un) if len(cur.fetchall())<=0: for k in result.keys(): seq=int(k.split('_')[1]) if answers[seq]==result[k]: cur.execute("insert into 考试记录(学号,题号,结果) values(?,?,?)",(un,str(seq),1)) count+=1 else: cur.execute("insert into 考试记录(学号,题号,结果) values(?,?,?)",(un,str(seq),0)) con.commit() else: return "dup" des="总共题目数{},做对数{},共得分{}".format(len(result),count,count*3) return des else: return render_template('exam.html',who=un)@app.route('/upload',methods=['GET','POST'])def upload(): if request.method=='POST': f=request.files['file'] base_path = os.path.abspath(os.path.dirname(__file__)) upload_path = os.path.join(base_path,r'static\uploads',secure_filename(f.filename)) f.save(upload_path) xls_file = r".\static\uploads\students.xls" book = xlrd.open_workbook(xls_file) for sheet in book.sheets(): excel2db.read_excel(sheet) return "文件上传导入成功!" return render_template("upload.html")@app.route('/login',methods=['POST','GET'])def login(): if request.method == 'POST': user = request.form.get('username') pwd = request.form.get('password') con = sqlite3.connect("./DB/stuScores.db") cur = con.cursor() cur.execute("select * from 学生 where 学号='%s' and 密码='%s'" % (user,pwd)) r = cur.fetchall() if len(r)>0: session['sid'] =r[0][1] return "suc" else: return "fai" return render_template("login.html")if __name__ == '__main__': app.run(debug=True)
数据库部分
这样,我们接下来就可以针对每道题写sql来查询其正确率了。当然,这样的做法只适合每次测试生成一次数据库。如果要持续使用并记录数据,最好还是做好“考试”这个库,记录考试id,考试名称,添加时间等,用户登录后可以选择考试,保存的题号里面包含着考试号以保证唯一并可分析。
既然是极简,我们就暂时先保证能用,暂不更新以上功能。