Flask新手求助:如何对比表单请求与MySQL表数据判断是否已存在
问题分析与修复
你的代码存在几个关键逻辑错误,导致无法正确判断酒店是否已存在:
- POST请求逻辑位置错误:把表单提交的处理逻辑放在
while循环内部,导致第一次循环就会执行插入/提示操作并直接return,根本没机会遍历完所有酒店名称。 - 数据类型不匹配:
cur.fetchall()返回的是元组列表(比如[('酒店A',), ('酒店B',)]),你把names = h[i]赋值后,names是一个元组,和表单提交的字符串name对比永远不相等,所以每次都会执行插入。 - 游标过早关闭:
cur.close()之后,后续请求再使用该游标会报错,无需手动关闭游标,数据库连接会自动处理。 - 遍历逻辑错误:即使前面的问题都解决,你的遍历逻辑只要遇到第一个不匹配的酒店名就会插入,而不是检查完所有名称再判断是否重复。
推荐修复方案(数据库层面判断,更高效)
直接用SQL查询判断该酒店名是否存在,比手动遍历所有数据高效得多,代码逻辑也更清晰:
@app.route('/createHotel', methods=['GET', 'POST']) def createHotel(): if "loggedin" in session and session['role'] == 'admin': user = session["username"] userid = session["userid"] if request.method == "POST": # 检查所有必填字段是否齐全 required_fields = ['name', 'image', 'city', 'features', 'RoomCount', 'peakSeasonRate', 'OffPeakSeasonRate'] if all(field in request.form for field in required_fields): image = request.form["image"] name = request.form['name'] city = request.form['city'] features = request.form['features'] RoomCount = request.form['RoomCount'] peakSeasonRate = request.form['peakSeasonRate'] OffPeakSeasonRate = request.form['OffPeakSeasonRate'] # 查询数据库是否存在同名酒店 cur.execute('SELECT COUNT(*) FROM hotels WHERE name = %s', (name,)) count = cur.fetchone()[0] if count == 0: # 不存在则插入数据 cur.execute('INSERT INTO hotels (image, name, city, features, RoomCount, peakSeasonRate, OffPeakSeasonRate) VALUES (%s, %s, %s, %s, %s, %s, %s)', (image, name, city, features, RoomCount, peakSeasonRate, OffPeakSeasonRate)) mysql.connection.commit() flash('酒店添加成功', 'success') return redirect(url_for('hotelRecord')) else: flash('该酒店已存在于数据库中', 'danger') else: flash('请填写所有必填字段', 'danger') # GET请求或POST请求处理完成后渲染页面 return render_template("createHotel.html", user=user, userid=userid,) return redirect(url_for("home"))
若坚持手动遍历数据(不推荐)
如果一定要通过遍历已有的酒店名来判断,需要调整逻辑顺序:
@app.route('/createHotel', methods=['GET', 'POST']) def createHotel(): if "loggedin" in session and session['role'] == 'admin': user = session["username"] userid = session["userid"] if request.method == "POST": required_fields = ['name', 'image', 'city', 'features', 'RoomCount', 'peakSeasonRate', 'OffPeakSeasonRate'] if all(field in request.form for field in required_fields): image = request.form["image"] name = request.form['name'] city = request.form['city'] features = request.form['features'] RoomCount = request.form['RoomCount'] peakSeasonRate = request.form['peakSeasonRate'] OffPeakSeasonRate = request.form['OffPeakSeasonRate'] # 获取所有酒店名并提取字符串 cur.execute('SELECT name FROM hotels') hotel_names = [row[0] for row in cur.fetchall()] # 判断是否存在重复 if name not in hotel_names: cur.execute('INSERT INTO hotels (image, name, city, features, RoomCount, peakSeasonRate, OffPeakSeasonRate) VALUES (%s, %s, %s, %s, %s, %s, %s)', (image, name, city, features, RoomCount, peakSeasonRate, OffPeakSeasonRate)) mysql.connection.commit() flash('酒店添加成功', 'success') return redirect(url_for('hotelRecord')) else: flash('该酒店已存在于数据库中', 'danger') else: flash('请填写所有必填字段', 'danger') return render_template("createHotel.html", user=user, userid=userid,) return redirect(url_for("home"))
额外建议
- 给
hotels表的name字段添加唯一约束,从数据库层面避免重复数据,即使代码有漏洞也能保证数据一致性。 - 表单字段验证可以使用Flask-WTF等库,更规范且能减少重复代码。
- 操作数据库时建议用
try-except捕获异常,避免程序崩溃。
内容的提问来源于stack exchange,提问作者Sefiu Rasheed
相关产品推荐
相关产品推荐

