Flask WTForms FieldList与BooleanField

问题描述:

我想用复选框生成文件列表。我试图使用FieldList,但它不能如我所料。而不是具有分配的文件名的复选框我得到的复选框的标签以包含FieldList对象的变量命名。有什么方法可以解决它吗?Flask WTForms FieldList与BooleanField

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) 

模板/ 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不应与使用BooleanField

注意:由于HTML发送值的限制,FieldList不能包含BooleanFieldSubmitField实例。

(即使HTML输出出现有效。)这就是说,你没有看到你期待看到,因为append_entry的第一个参数接受表单输入的值,而不是它的标签是什么。

相反,我建议动态创建的窗体类:

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表示将有在顶部“提交”按钮,因为库呈现在他们”的顺序领域重新定义。 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) 
+0

谢谢。这正是我所期待的。 – przemekk