Flask表单提交后无法新增数据库条目问题求助
Flask表单提交后数据库无新增条目排查与修复
问题现象
Flask表单与数据库模型已定义为独立类,视图函数运行正常,HTML页面渲染无异常。点击提交按钮后页面可正常重定向,但数据库始终无法新增条目,其余功能均正常。
Flask表单(简化版)
class CafeForm(FlaskForm): name = StringField("Cafe Name", [validators.DataRequired()]) map_url = StringField("Location on Google Maps (URL)", [validators.DataRequired(), validators.URL()]) img_url = StringField("Image(s) of Cafe (URL)", [validators.DataRequired(), validators.URL()]) location = StringField("Neighborhood or Village", [validators.DataRequired()]) has_sockets = SelectField("Device Charging Available?", choices=[("False", "False"), ("True", "True")], validators=[DataRequired()]) seats = StringField("Approximate Seating Capacity", [validators.DataRequired()]) coffee_price = StringField("Price of Large Black", [validators.DataRequired()]) submit = SubmitField("Submit")
数据库模型
class Cafes(db.Model): __tablename__ = "cafe" id = db.Column(db.Integer, primary_key=True) name = db.Column(db.Text(250), unique=True, nullable=False) map_url = db.Column(db.Text(250), nullable=False) img_url = db.Column(db.Text(250), nullable=False) location = db.Column(db.Text(100), nullable=False) has_sockets = db.Column(db.Boolean, server_default="false", default=False) seats = db.Column(db.Integer) coffee_price = db.Column(db.Text(100))
视图函数
@app.route("/new-cafe", methods=["GET", "POST"]) def add_cafe(): form = CafeForm(request.form) if form.validate_on_submit(): cafe = Cafes( name=form.name.data, map_url=form.map_url.data, img_url=form.img_url.data, location=form.location.data, has_sockets=form.has_sockets.data, seats=form.seats.data, coffee_price=form.coffee_price.data ) db.session.add(cafe) db.session.commit() return redirect(url_for('cafes')) print(form.errors) return render_template("new-cafe.html", form=form)
HTML表单代码
<form method="POST" action="/cafes"> {{ form.csrf_token }} {{ form.hidden_tag() }} {{ form.name.label }} {{ form.name(size=20) }} <br> {{ form.map_url.label }} {{ form.map_url(size=20) }} <br> {{ form.img_url.label }} {{ form.img_url(size=20) }} <br> {{ form.location.label }} {{ form.location(size=20) }} <br> {{ form.has_sockets.label }} {{ form.has_sockets(size=1) }} <br> {{ form.seats.label }} {{ form.seats(size=20) }} <br> {{ form.coffee_price.label }} {{ form.coffee_price(size=20) }} <br> <input type="submit" value="Add Cafe"> </form>
问题排查与修复方案
1. 表单提交路径不匹配
HTML表单的action="/cafes"指向了错误的路由,而处理提交逻辑的视图函数路由是/new-cafe,导致表单提交后直接跳转到/cafes,完全没触发新增数据的代码。
修复:将表单的action改为/new-cafe,或直接省略action(默认提交到当前页面路由):
<form method="POST">
2. 数据类型不匹配
has_sockets:表单返回的是字符串"True"/"False",但数据库模型是Boolean类型,直接赋值会导致数据无法正确解析。seats:表单是StringField,数据库是Integer类型,若输入非数字内容会触发转换错误,导致提交失败。
修复:在视图函数中手动转换数据类型:
cafe = Cafes( name=form.name.data, map_url=form.map_url.data, img_url=form.img_url.data, location=form.location.data, has_sockets=form.has_sockets.data == "True", seats=int(form.seats.data) if form.seats.data.isdigit() else None, coffee_price=form.coffee_price.data )
3. 验证错误无法排查
视图中print(form.errors)放在return redirect之后,永远不会执行,无法得知表单是否验证失败。
修复:将打印代码移到重定向之前,或在模板中渲染错误信息:
if form.validate_on_submit(): # ... 数据处理代码 db.session.commit() print(form.errors) return redirect(url_for('cafes')) else: print(form.errors) # 打印验证错误
模板中添加错误提示:
{% for field, errors in form.errors.items() %} <div style="color:red;">{{ field }}: {{ ', '.join(errors) }}</div> {% endfor %}
4. 唯一键冲突
数据库模型中name字段设置了unique=True,若提交已存在的咖啡馆名称,会触发唯一键约束错误,导致事务回滚。
修复:添加异常捕获处理冲突:
try: db.session.add(cafe) db.session.commit() except IntegrityError: db.session.rollback() # 可在模板中返回"该咖啡馆名称已存在"的提示
内容的提问来源于stack exchange,提问作者ScoZone74
相关产品推荐
相关产品推荐

