简体   繁体   English

Flask WTForm 动态创建 WTForm 的 SelectField 元素

[英]Flask WTForm Creating WTForm's SelectField Element dynamically

I have a table in my database that houses some staff and each staff has an allocated task id .我的数据库中有一个表,其中包含一些员工,每个员工都有一个分配的任务 ID I want to dynamically create select fields according to the number of staff that has a particular task id.我想根据具有特定任务 ID 的员工数量动态创建选择字段。 For example, if there are 3 staff with task id 1 , there will be three select fields (with 5 dropdown items each) In form.py例如,如果有3 个任务 ID 为1的员工,将有三个选择字段(每个字段有5 个下拉项)在 form.py

 class DynamicForm(Form):
    @classmethod 
    def append_field(cls, name, field):
        setattr(cls, name, field)
        return cls  

In routes.py -- main file在 routes.py -- 主文件

assigns = Project_Users.query.filter_by(project_id=id).all() 
// query the database to get all the staff under the project using the project id 
l = len(assigns) // length/ number of staff

d = DynamicForm() // from form.py
for e in range(l):         
  d.append_field(assigns[e].admin.first_name,SelectField(assigns[e].admin.first_name, validators=[DataRequired()], choices=[('0', 'No Task'),( '1','Site Acquisition'),('2','Installation'),('3','Configuration'), ('4','Commission')]))

    d.append_field('submit', SubmitField('SAVE')) // this is outside the for loop

In html template在 html 模板中

<form action="/project/{{ project.id }}/tasks" method="POST">
                  {{ d.hidden_tag() }}
                <table class="table is-stripped" style="width: 100%;">
                    <tbody>
                      {% for g in d %}
                      <tr>
                        <td>{{ g.label }}</td>
                        <td>{{ g }}</td>
                      </tr>
                      {% endfor %}

                      </tbody>
                  </table>
              </form>

The codes above is working, but it does not change and the number of staff changes for example, project 1 has 3 staff and it rendered three selectfields but when project 2 which has 2 staff is rendered 3 staff and 3 selectfields appears上面的代码是有效的,但它并没有改变,员工的数量也发生了变化,例如,项目 1 有 3 名员工,它呈现了三个选择字段,但是当项目 2 有 2 名员工呈现时,出现了 3 名员工和 3 个选择字段

Try constructing your form dynamically overwriting the constructor with arguments:尝试构造您的表单,动态地用参数覆盖构造函数:

class DynamicForm(Form):
    submit = SubmitField

    def __init__(self, **kwargs):
        assigns = Project_Users.query.filter_by(project_id=kwargs['id']).all()
        for ass in assigns:         
            setattr(DynamicForm,
                    ass.admin.first_name,
                    SelectField(ass.admin.first_name, 
                                validators=[DataRequired()], 
                                choices=[('0', 'No Task'),
                                         ( '1','Site Acquisition'),
                                         ('2','Installation'),
                                         ('3','Configuration'),
                                         ('4','Commission')]))
        super().__init__()

Then you call it like然后你称它为

d = DynamicForm(id=1)

Technically the difference between this and your form is that you add class level attributes after you have initialised the form, and after the base Form has run.从技术上讲,这与您的表单之间的区别在于,您在初始化表单之后以及在运行基本Form之后添加类级别属性。 Ie there is a difference between:即有以下区别:

DynamicForm(Form):
    def __init__(self)
        super().__init__() # calls Form.__init__()
        # extra stuff

and

DynamicForm(Form):
    def __init__(self)
        # extra stuff
        super().__init__() # calls Form.__init__() and acts on extra stuff.

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM