Flask表单POST提交后验证失败,无法存入数据库求助
问题排查与修复方案
核心问题1:缺少CSRF令牌验证
Flask-WTF默认启用CSRF保护,你的HTML表单中没有包含CSRF令牌字段,这是导致表单验证失败的最直接原因。
修复方法:在HTML表单内添加CSRF令牌字段,使用Flask-WTF提供的form.hidden_tag():
<form method="POST" action="/contacto"> {{ form.hidden_tag() }} <input name="name" type="text" class="feedback-input" placeholder="Nombre" /> <input name="email" type="text" class="feedback-input" placeholder="Email" /> <input name="phone_number" type="text" class="feedback-input" placeholder="Teléfono" /> <textarea name="message" class="feedback-input" placeholder="Mensaje"></textarea> <input type="submit" value="Enviar"/> <div class="check_aviso"> </div> </form>
若不想依赖模板渲染,也可以手动添加隐藏字段:
<input type="hidden" name="csrf_token" value="{{ csrf_token() }}">
核心问题2:Email字段验证逻辑错误
ContactInfoForm中email字段仅添加了Email()验证器,但模型允许email为空。当用户不填写email时,空字符串不符合邮箱格式,Email()验证器会触发错误,导致表单验证失败。
修复方法:给email字段添加Optional()验证器,允许字段为空,同时给name字段添加DataRequired()匹配模型的非空要求:
# forms.py from wtforms.validators import Email, Optional, DataRequired from wtforms import TextAreaField class ContactInfoForm(FlaskForm): name = StringField('Nombre', validators=[DataRequired()]) email = StringField('Correo electrónico', validators=[Optional(), Email()]) phone_number = StringField('Número de teléfono') message = TextAreaField('Mensaje') # 替换为TextAreaField匹配HTML的textarea
其他优化建议
- Message字段类型修正:将forms.py中的
message字段从StringField改为TextAreaField,与HTML中的<textarea>对应,避免潜在的字段数据截断问题。 - 简化路由逻辑:使用Flask-WTF的
form.validate_on_submit()替代手动判断请求方法和验证状态,代码更简洁:
# routes.py @app.route('/contacto', methods=['GET', 'POST']) def contacto(): form = ContactInfoForm() context = {'form': form} if form.validate_on_submit(): print("also validated") name = form.name.data email = form.email.data phone_number = form.phone_number.data message = form.message.data user_info = ContactInfo(name=name, email=email, phone_number=phone_number, message=message) db.session.add(user_info) db.session.commit() send_contact_info_email(name, email, phone_number, message) flash( 'Muchas gracias por la información, en la brevedad ' + 'nos pondremos en contacto con usted.','success' ) return redirect(url_for('contacto', _anchor='form')) elif request.method == 'POST': flash('Data not saved','error') return render_template('contacto.html', **context)
内容的提问来源于stack exchange,提问作者add
相关产品推荐
相关产品推荐

