Flask + WTForms + SelectMultipleField和动态选项

12

我正在尝试使用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>

基本上所有的功能都按照预期工作;在未分配列表中双击项目会将其移动到已分配列表。问题出现在提交表单进行验证时,因为“已分配”字段上的.choices属性最初是“[ ]”,并且仍然希望它是“[ ]”,而不是我们提供的新选项列表。

有人知道一个好方法来解决这个问题吗?我想覆盖表单的pre_validate()函数,并更新assigned.choices以包含来自“可用”列表的所有值,但这感觉不太“对”,并且可以用于在提交时从客户端提交随机值。

谢谢, David。

1个回答

13

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()失败,则表单将被重置,因此所做出的任何选择都将被撤消。我想我可以解决这个问题,因为与在字段本身上预验证相比,这更容易些。谢谢, 大卫 - David Dyball
1
只是一个更新。我采纳了Sean的建议,在发布后修改了.choices,但加入了一些代码来获取提交的选择,然后再修改它们以包含AVAILABLE_CHOICES列表。这使得如果form.validate()因任何原因失败,我可以将.choice属性恢复为提交的选择。感谢Sean的帮助。 - David Dyball

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接