You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Flask新手求助:如何对比表单请求与MySQL表数据判断是否已存在

问题分析与修复

你的代码存在几个关键逻辑错误,导致无法正确判断酒店是否已存在:

  1. POST请求逻辑位置错误:把表单提交的处理逻辑放在while循环内部,导致第一次循环就会执行插入/提示操作并直接return,根本没机会遍历完所有酒店名称。
  2. 数据类型不匹配:cur.fetchall()返回的是元组列表(比如[('酒店A',), ('酒店B',)]),你把names = h[i]赋值后,names是一个元组,和表单提交的字符串name对比永远不相等,所以每次都会执行插入。
  3. 游标过早关闭:cur.close()之后,后续请求再使用该游标会报错,无需手动关闭游标,数据库连接会自动处理。
  4. 遍历逻辑错误:即使前面的问题都解决,你的遍历逻辑只要遇到第一个不匹配的酒店名就会插入,而不是检查完所有名称再判断是否重复。

推荐修复方案(数据库层面判断,更高效)

直接用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"))

额外建议

  1. 给hotels表的name字段添加唯一约束,从数据库层面避免重复数据,即使代码有漏洞也能保证数据一致性。
  2. 表单字段验证可以使用Flask-WTF等库,更规范且能减少重复代码。
  3. 操作数据库时建议用try-except捕获异常,避免程序崩溃。

内容的提问来源于stack exchange,提问作者Sefiu Rasheed

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.23 18:21:08