【问题标题】:Dynamic Flask Checkbox Form Composition with WTFlask使用 WTFlask 组成动态 Flask 复选框表单
【发布时间】:2021-12-31 06:25:20
【问题描述】:

我在将WTForms documentation 中的代码应用到我的用例时遇到了一些问题(请参阅“动态表单组合”部分)。我的目标是使用字符串列表(list_a,可变长度)作为参数来生成一系列复选框表单。例如,如果list_a = ['one, 'two'],则输出将是一个带有两个标记为“一”和“二”的复选框的表单。文档说要使用这个:

def my_view():
    class F(MyBaseForm):
        pass

    F.username = StringField('username')
    for name in iterate_some_model_dynamically():
        setattr(F, name, StringField(name.title()))

    form = F(request.POST, ...)
    # do view stuff

在我尝试使用它时,我想出了这个:

def wrapper_func(list_a):
    class Prefs(FlaskForm):
        pass

    for ele in list_a:
        setattr(Prefs, ele, BooleanField(ele) )

    form = Prefs(request.POST, ...)

谁能帮我清理它以使其正常工作?我不确定最后一行还有什么内容,或者在这种情况下是否允许使用列表。任何意见将不胜感激!

【问题讨论】:

    标签: python python-3.x flask flask-wtforms wtforms


    【解决方案1】:

    根据您的问题,很难确定您使用的是WTForms 还是Flask-WTF。文档链接指向前者,而您的示例使用 FlaskForm 类,后者是后者的一部分。

    以下简约示例是使用 WTForms 制作的。

    项目结构:

    your_project_folder
    ├───forms
    │   ├───__init__.py
    │   └───dynamic_form.py
    ├───templates
    │   └───main.html
    ├───venv
    │   └───your_virtual_environment_files
    └───server.py
    

    dynamic_form.py 包含没有表单实例化的包装函数(它只返回动态创建的表单类):

    from wtforms import Form, BooleanField
    
    
    def wrapper_func(list_a):
        class Prefs(Form):
            pass
    
        for ele in list_a:
            setattr(Prefs, ele, BooleanField(ele))
    
        return Prefs
    

    main.html 包含使用 Jinja2 语法生成表单的 HTML 代码:

    <!doctype html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport"
              content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
        <meta http-equiv="X-UA-Compatible" content="ie=edge">
        <title>Document</title>
    </head>
    <body>
    <form method="POST">
        {% for field in form %}
            <div>{{ field.label }}: {{ field }}</div>
        {% endfor %}
        <button type="submit">Submit</button>
    </form>
    </body>
    </html>
    

    server.py 将所有内容放在一起:

    from flask.app import Flask
    from flask import request, render_template, redirect
    from forms.dynamic_form import wrapper_func
    
    
    app = Flask('form_app')
    
    
    @app.route('/', methods=['GET', 'POST'])
    def main():
        input_list = ['one', 'two', 'three']  # generate it as needed
        prefs = wrapper_func(input_list)
        form = prefs(request.form)
        if request.method == 'POST' and form.validate():
            # do your logic with the submitted form data here
            return redirect('/')
        return render_template("main.html", form=form)
    
    
    if __name__ == '__main__':
        app.run(host='localhost', port=3456, debug=True)
    

    最后两行仅用于开发目的!

    如果这个例子有帮助,请告诉我!

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-05-23
      • 2018-03-18
      • 2023-03-17
      • 1970-01-01
      • 2015-11-23
      • 2014-04-07
      • 2020-05-15
      • 1970-01-01
      相关资源
      最近更新 更多