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

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

其他优化建议

  1. Message字段类型修正:将forms.py中的message字段从StringField改为TextAreaField,与HTML中的<textarea>对应,避免潜在的字段数据截断问题。
  2. 简化路由逻辑:使用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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.05 01:18:14