我已经使用 WTForms FieldList、宏和 Javascript 创建了动态字段。
使用此代码验证许多字段(StringField、SelectField 等),我可以动态添加许多字段,它们会验证和更新我的 Sqlite3 数据库。但是我现在希望能够动态添加文件。
文件上传的标准 Flask-WTF 代码如下所示:如何利用它对 FieldList 表单进行验证?
if form.validate_on_submit():
f_fileA = form.inputname.data
filename_fileA = secure_filename(f_fileA.filename)
f_fileA.save(os.path.join(
UPLOAD_FOLDER, filename_fileA
))
我的代码 表格
forms.py
class ChildForm(Form):
childAinput_1 = StringField(
'ChildA input 1'
)
childAinput_2 = IntegerField(
'ChildA input 2'
)
category = SelectField(
'Category',
choices=[('cat1', 'Category 1'), ('cat2', 'Category 2')]
)
fileA = FileField(
'FileA'
)
class MainForm(FlaskForm):
parentinput_1 = StringField(
'Parent input 1'
)
parentinput_2 = StringField(
'Parent input 2'
)
childrenA = FieldList(
FormField(ChildForm),
min_entries=1,
max_entries=20
)
我的带有表单字段的 HTML 模板
form.html template
<a id="add" href="#">Add ChildA</a>
{# Show all subforms #}
<form id="childA-form" action="" method="POST" role="form">
{{ form.hidden_tag() }}
{# show parents fields #}
<div>
{{ form.parentinput_1.label }}
{{ form.parentinput_1 }}
</div>
<div>
{{ form.parentinput_2.label }}
{{ form.parentinput_2 }}
</div>
<div id="subforms-container">
{% for subform in form.childrenA %}
{{ macros.render_childA_form(subform, loop.index0) }}
{% endfor %}
</div>
<button type="submit">Send</button>
</form>
{% if form.errors %}
{{ form.errors }}
{% endif %}
{# Form template #}
{{ macros.render_childA_form(_template, '_') }}
当前表单验证(尚未添加文件上传)
routes.py
@bp.route('/', methods=['GET', 'POST'])
def index():
form = MainForm()
template_form = ChildForm(prefix='childrenA-_-')
if form.validate_on_submit():
# Create parent
new_parent = Parent(
parentinput_1 = form.parentinput_1.data,
parentinput_2 = form.parentinput_2.data
)
db.session.add(new_parent)
for childAe in form.childrenA.data:
new_childA = ChildA(**childAe)
# Add to parent
new_parent.childrenA.append(new_childA)
db.session.commit()
return render_template(
'index.html',
form=form,
_template=template_form
)
如果有用的宏是:
macros.html
{%- macro render_childA_form(subform, index) %}
<div id="childA-{{ index }}-form" class="{% if index != '_' %}subform{% else %}is-hidden{% endif %}" data-index="{{ index }}">
<div>
{{ subform.childAinput_1.label }}
{{ subform.childAinput_1 }}
</div>
<div>
{{ subform.childAinput_2.label }}
{{ subform.childAinput_2}}
</div>
<div>
{{ subform.category.label }}
{{ subform.category }}
</div>
<div>
{{ subform.fileA.label }}
{{ subform.fileA }}
</div>
<a class="remove" href="#">Remove</a>
<hr/>
</div>
{%- endmacro %}
我的模特
models.py
class Parent(db.Model):
"""Stores parents."""
__tablename__ = 'parents'
parentinput_1 = db.Column(db.String(100))
parentinput_2 = db.Column(db.String(100))
id = db.Column(db.Integer, primary_key=True)
class ChildA(db.Model):
"""Stores childrenA of a parent."""
__tablename__ = 'childrenA'
id = db.Column(db.Integer, primary_key=True)
parent_id = db.Column(db.Integer, db.ForeignKey('parents.id'))
childAinput_1 = db.Column(db.String(100))
childAinput_2 = db.Column(db.Integer)
category = db.Column(db.String(4))
fileA = db.Column(db.String(255))
# Relationship
parent = db.relationship(
'Parent',
backref=db.backref('childrenA', lazy='dynamic', collection_class=list)
)
(模型、路线和表格实际上在一个文件中,但为了便于阅读,我在问题中将它们分开)
非常感谢
即使您使用 FormFields 列表,该过程也与标准示例代码相同。
您可以遍历所有嵌套表单并查询相应 FileField 的值并保存生成的文件。
这是我根据您的代码部分编写的简单示例。