使用WTForms Dynamic Fields遇Request无post属性的AttributeError问题
解决WTForms Dynamic Fields中AttributeError: 'Request' object has no attribute 'post'错误
错误根源
Flask的request对象不存在post属性,你在代码中错误使用了request.post;同时当前代码仅在GET请求时处理动态字段,POST请求时未同步处理,会导致表单提交时动态字段的验证或数据获取失败。
修正后的完整代码
路由处理函数
from datetime import datetime, timedelta from flask import request, redirect, url_for, flash, render_template from flask_login import login_required, current_user from wtforms import StringField @app.route("/create", methods=["POST", "GET"]) @login_required def create(): # 统一创建动态表单结构,GET/POST请求都执行 cfv = customfields.find({"_id": current_user.user_json['_id']}) dynamic = WTFormsDynamicFields() for value in cfv: if value['fieldType'] == "Text Field": dynamic.add_field(value['fieldName'], value['fieldName'], StringField) if request.method == "POST": # POST请求传入request.form处理表单数据 form = dynamic.process(CreateRecord, request.form) if form.validate_on_submit(): # 从表单对象获取所有字段值(含动态字段) name = form.name.data phone = form.phone.data email = form.email.data company = form.company.data frequency = form.frequency.data datefc = form.date.data adate = datetime.today() # 计算下次联系时间 if frequency == "Weekly": nContactTime = datefc + timedelta(days=7) elif frequency == "Monthly": nContactTime = datefc + timedelta(days=30) elif frequency == "Quarterly": nContactTime = datefc + timedelta(days=90) # 收集动态字段数据 dynamic_fields_data = {} for field_info in cfv: if field_info['fieldType'] == "Text Field": field_name = field_info['fieldName'] dynamic_fields_data[field_name] = getattr(form, field_name).data # 插入数据库,包含动态字段 people.insert_one({ "name": name, "phone": phone, "email": email, "company": company, "frequency": frequency, "parentrecord": current_user.user_json['_id'], "dateadded": adate.strftime("%x"), "datefc": datefc, "nextContact": nContactTime, **dynamic_fields_data }) flash('记录已成功添加。') return redirect(url_for('profile')) else: # GET请求无需传入表单数据 form = dynamic.process(CreateRecord) return render_template('create.html', form=form, auth=current_user.is_authenticated)
表单类(保持不变)
from flask_wtf import FlaskForm from wtforms import StringField, SelectField, DateField, SubmitField from wtforms.validators import DataRequired class CreateRecord(FlaskForm): name = StringField('姓名', validators=[DataRequired()]) phone = StringField('电话') email = StringField('邮箱') company = StringField('公司', validators=[DataRequired()]) frequency = SelectField('跟进频率', choices=[('Weekly', '每周'), ('Monthly', '每月'), ('Quarterly', '每季度')]) date = DateField('首次联系日期', validators=[DataRequired()]) submit = SubmitField('创建记录')
模板优化(可选)
{% for field in form %} {% if field.type not in ['CSRFTokenField', 'SubmitField'] %} <div class="form-group mb-3"> {{ field.label(class="form-label") }} {{ field(class="form-control") }} {% if field.errors %} {% for error in field.errors %} <small class="text-danger d-block mt-1">{{ error }}</small> {% endfor %} {% endif %} </div> {% elif field.type == 'SubmitField' %} {{ field(class="btn btn-primary") }} {% endif %} {% endfor %}
关键修改点
- 替换错误的
request.post:POST请求时传入request.form,GET请求时无需传入表单数据,避免属性错误。 - 统一动态字段逻辑:将动态字段的创建代码移到请求判断之外,确保GET和POST请求的表单结构完全一致,防止验证失败。
- 通过表单对象获取数据:不再直接从
request.form取值,而是使用表单对象的data属性,确保能获取到动态字段的输入值。
内容的提问来源于stack exchange,提问作者David
相关产品推荐
相关产品推荐

