带有 BooleanField 的 Flask WTForms FieldList
Flask WTForms FieldList with BooleanField
我想生成带有复选框的文件列表。我试过使用 FieldList 但它没有像我预期的那样工作。我得到的不是带有指定文件名的复选框,而是带有以包含 FieldList 对象的变量命名的标签的复选框。有什么办法可以解决吗?
app.py:
from flask import Flask, render_template
from flask_bootstrap import Bootstrap
from flask_wtf import FlaskForm
from wtforms import BooleanField, FieldList, SubmitField
app = Flask(__name__)
app.config['SECRET_KEY'] = 'development'
Bootstrap(app)
filenames = ['1.jpg', '2.jpg', '3.jpg', '4.jpg']
class FileListForm(FlaskForm):
filename = FieldList(BooleanField(), 'Files')
submit = SubmitField('Submit')
@app.route('/')
def listfiles():
form = FileListForm()
for filename in filenames:
form.filename.append_entry(filename)
return render_template('index.html',
form=form)
if __name__ == '__main__':
app.run(debug=True, port=5001)
templates/index.html
{% import "bootstrap/wtf.html" as wtf %}
{{ wtf.quick_form(form) }}
包:
click==6.7
dominate==2.3.1
Flask==0.12.2
Flask-Bootstrap==3.3.7.1
Flask-WTF==0.14.2
itsdangerous==0.24
Jinja2==2.9.6
MarkupSafe==1.0
visitor==0.1.3
Werkzeug==0.12.2
WTForms==2.1
根据文档,WTForms' FieldList
shouldn't be used with BooleanField
:
Note: Due to a limitation in how HTML sends values, FieldList
cannot enclose BooleanField
or SubmitField
instances.
(即使 HTML 输出看起来有效。)也就是说,您没有看到您期望看到的内容,因为 append_entry
的第一个参数接受表单输入的值,不是它的标签。
相反,我建议动态创建表单 class:
filenames = ['1.jpg', '2.jpg', '3.jpg', '4.jpg']
class FileListFormBase(FlaskForm):
submit = SubmitField('Submit')
def file_list_form_builder(filenames):
class FileListForm(FileListFormBase):
pass
for (i, filename) in enumerate(filenames):
setattr(FileListForm, 'filename_%d' % i, BooleanField(label=filename))
return FileListForm()
@app.route('/')
def listfiles():
form = file_list_form_builder(filenames)
return render_template('index.html', form=form)
注意:默认的 HTML 表示将在顶部显示 "Submit" 按钮,因为库会按照定义的顺序呈现字段。 WTForms 本身不支持排序,所以这可能是一个更好的解决方案,尽管它不太优雅:
filenames = ['1.jpg', '2.jpg', '3.jpg', '4.jpg']
def file_list_form_builder(filenames):
class FileListForm(FlaskForm):
pass
for (i, filename) in enumerate(filenames):
setattr(FileListForm, 'filename_%d' % i, BooleanField(label=filename))
setattr(FileListForm, 'submit', SubmitField('Submit'))
return FileListForm()
@app.route('/')
def listfiles():
form = file_list_form_builder(filenames)
return render_template('index.html', form=form)
以防将来对任何人有帮助。这就是我实现此解决方案的神社部分的方式。
我创建了一个变量名列表以发送到模板。
在我的例子中,我需要根据计数动态创建多个字段。
这些名称需要与您在构建表单时创建的名称相匹配,例如在上述给定问题的选定解决方案中。
variable_names_list = []
for i in range(1, count+1):
variable_names_list.append([f'var1_name_{i}',f'var2_name_{i}',f'var3_name_{i}',f'var4_name_{i}'])
在渲染模板语句中将其发送到模板
然后使用以下 jinja 来显示您的表单项
<div class="row">
<table class="table table-bordered">
<tbody>
{{ form.csrf_token }}
{% for variable_names in variable_names_list %}
<tr>
{% for variable in variable_names %}
<td>
{{ form[variable] }}
</td>
{% endfor %}
</tr>
{% endfor %}
</tbody>
</table>
</div>
此解决方案的关键部分是这一行:
{{ form[variable] }}
我花了一段时间才弄明白这是单独访问表单项的方法。
希望这对以后的人有所帮助。
干杯
我想生成带有复选框的文件列表。我试过使用 FieldList 但它没有像我预期的那样工作。我得到的不是带有指定文件名的复选框,而是带有以包含 FieldList 对象的变量命名的标签的复选框。有什么办法可以解决吗?
app.py:
from flask import Flask, render_template
from flask_bootstrap import Bootstrap
from flask_wtf import FlaskForm
from wtforms import BooleanField, FieldList, SubmitField
app = Flask(__name__)
app.config['SECRET_KEY'] = 'development'
Bootstrap(app)
filenames = ['1.jpg', '2.jpg', '3.jpg', '4.jpg']
class FileListForm(FlaskForm):
filename = FieldList(BooleanField(), 'Files')
submit = SubmitField('Submit')
@app.route('/')
def listfiles():
form = FileListForm()
for filename in filenames:
form.filename.append_entry(filename)
return render_template('index.html',
form=form)
if __name__ == '__main__':
app.run(debug=True, port=5001)
templates/index.html
{% import "bootstrap/wtf.html" as wtf %}
{{ wtf.quick_form(form) }}
包:
click==6.7
dominate==2.3.1
Flask==0.12.2
Flask-Bootstrap==3.3.7.1
Flask-WTF==0.14.2
itsdangerous==0.24
Jinja2==2.9.6
MarkupSafe==1.0
visitor==0.1.3
Werkzeug==0.12.2
WTForms==2.1
根据文档,WTForms' FieldList
shouldn't be used with BooleanField
:
Note: Due to a limitation in how HTML sends values,
FieldList
cannot encloseBooleanField
orSubmitField
instances.
(即使 HTML 输出看起来有效。)也就是说,您没有看到您期望看到的内容,因为 append_entry
的第一个参数接受表单输入的值,不是它的标签。
相反,我建议动态创建表单 class:
filenames = ['1.jpg', '2.jpg', '3.jpg', '4.jpg']
class FileListFormBase(FlaskForm):
submit = SubmitField('Submit')
def file_list_form_builder(filenames):
class FileListForm(FileListFormBase):
pass
for (i, filename) in enumerate(filenames):
setattr(FileListForm, 'filename_%d' % i, BooleanField(label=filename))
return FileListForm()
@app.route('/')
def listfiles():
form = file_list_form_builder(filenames)
return render_template('index.html', form=form)
注意:默认的 HTML 表示将在顶部显示 "Submit" 按钮,因为库会按照定义的顺序呈现字段。 WTForms 本身不支持排序,所以这可能是一个更好的解决方案,尽管它不太优雅:
filenames = ['1.jpg', '2.jpg', '3.jpg', '4.jpg']
def file_list_form_builder(filenames):
class FileListForm(FlaskForm):
pass
for (i, filename) in enumerate(filenames):
setattr(FileListForm, 'filename_%d' % i, BooleanField(label=filename))
setattr(FileListForm, 'submit', SubmitField('Submit'))
return FileListForm()
@app.route('/')
def listfiles():
form = file_list_form_builder(filenames)
return render_template('index.html', form=form)
以防将来对任何人有帮助。这就是我实现此解决方案的神社部分的方式。
我创建了一个变量名列表以发送到模板。 在我的例子中,我需要根据计数动态创建多个字段。 这些名称需要与您在构建表单时创建的名称相匹配,例如在上述给定问题的选定解决方案中。
variable_names_list = []
for i in range(1, count+1):
variable_names_list.append([f'var1_name_{i}',f'var2_name_{i}',f'var3_name_{i}',f'var4_name_{i}'])
在渲染模板语句中将其发送到模板 然后使用以下 jinja 来显示您的表单项
<div class="row">
<table class="table table-bordered">
<tbody>
{{ form.csrf_token }}
{% for variable_names in variable_names_list %}
<tr>
{% for variable in variable_names %}
<td>
{{ form[variable] }}
</td>
{% endfor %}
</tr>
{% endfor %}
</tbody>
</table>
</div>
此解决方案的关键部分是这一行:
{{ form[variable] }}
我花了一段时间才弄明白这是单独访问表单项的方法。
希望这对以后的人有所帮助。
干杯