【问题标题】:Flask + WTForms + SelectMultipleField and Dynamic ChoicesFlask + WTForms + SelectMultipleField 和动态选择
【发布时间】:2012-10-12 09:07:25
【问题描述】:

我正在尝试使用 WTForms.SelectMultipleField 来管理表单上的一些动态选择,但在提交验证之前在客户端修改它时遇到了一些困难。

基本上我有两个 SelectMultipleField 选项:

class MyForm(Form):
    assigned = SelectMultipleField('Assigned', choices=[])
    available = SelectMultipleField('Available', choices=[('1','1'),('2','2')])

我正在使用 Flask 来渲染 Jinja2 模板,如下所示:

@app.view("/myview", methods=['GET','POST'])
def myview():
    form = MyForm(request.form)
    if request.method == 'POST' and form.validate():
        return render_template("success.html")
    else:
        return render_template("index.html", form=form)

在我的模板中我有这个:

<script type="text/javascript">
    function assign_object() {
        return !$('#available option:selected').remove().appendTo('#assigned');
    };

    function unassign_object() {
        return !$('#assigned option:selected').remove().appendTo('#available');
    }

    $(document).ready( function() {
        $('#available').dblclick( assign_object );
        $('#assigned').dblclick( unassign_object );
    });
</script>

<form action="/myview" method="post" name="assign_objects">
    {{ render_field(form.a) }}
    {{ render_field(form.b) }}
    <input type="submit" value="Assign" name="assign_button"/>
</form>

基本上所有这些都按预期工作;双击未分配列表中的项目将其移至已分配列表。问题是提交表单进行验证时,因为“assigned”字段上的 .choices 属性最初是“[ ]”,但仍应为“[ ]”,而不是我们提供的新选项列表.

有没有人知道这样做的好方法?我在想我可以覆盖表单 pre_validate() 函数并更新assigned.choices以包含“可用”列表中的所有值,但这感觉不“正确”,可以用来从客户端提交随机值-一边提交。

干杯, 大卫。

【问题讨论】:

    标签: python flask wtforms


    【解决方案1】:

    POST 请求中更新choices

    AVAILABLE_CHOICES = [('1','1'),('2','2')]
    DEFAULT_CHOICES = []
    
    class MyForm(Form):
        assigned = SelectMultipleField('Assigned', choices=DEFAULT_CHOICES)
        available = SelectMultipleField('Available', choices=AVAILABLE_CHOICES)
    
    @app.view("/myview", methods=['GET','POST'])
    def myview():
        form = MyForm(request.form)
        if request.method == 'POST':
            form.assigned.choices = AVAILABLE_CHOICES
            if form.validate():
                return render_template("success.html")
            else:
                form.assigned.choices = DEFAULT_CHOICES
    
        return render_template("index.html", form=form)
    

    【讨论】:

    • 嗨,肖恩,感谢您的建议。虽然这有效,但它确实有一个不幸的副作用,即如果 validate() 失败,表单会被有效地重置,因此所做的任何选择都会被反转。我想我可以解决这个问题,因为它比在现场本身使用 pre_validate 更容易。谢谢,大卫
    • 只是一个更新。我接受了 Sean 的建议并在发布后修改了 .choices,但在修改它们以包含 AVAILABLE_CHOICES 列表之前放入了一些代码来获取提交的选择。如果 form.validate() 因任何原因失败,这允许我将 .choice 属性恢复为提交的选项。为肖恩的助攻干杯。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-04-05
    • 2011-07-28
    • 2012-11-13
    • 1970-01-01
    • 2019-07-23
    • 2012-08-23
    • 2021-05-15
    相关资源
    最近更新 更多