同一页面上具有相同单选字段的多个 WTForm
Multiple WTForms with Same Radio Field on Same Page
好吧,我在网上、文档和源代码中四处寻找,但我对这个问题一无所知。所以我正在使用 wtforms 和 bootstrap 开发一个 Flask 项目,我需要在一个页面上多次显示相同的表单。具体来说,这种形式:
class ProblemForm(Form):
def __init__(self, formdata=None, obj=None, prefix='', title="", **kwargs):
super(self.__class__, self).__init__(formdata=None, obj=None, prefix='', **kwargs)
self.title = title
opts = RadioField("Possible Corrections")
alias_of = StringField("Alias of")
select_alias = BooleanField("select_alias")
user_input = StringField("New Entry")
select_uinput = BooleanField("select_uinput")
在控制器逻辑中(见下文)我发现我可以创建一个 ProblemForm 实例数组,并根据会话中已有的数据为每个 "Problem" 设置选项。
@blueprint.route("/clean/review/<int:start>-<int:end>", methods=["GET", "POST"])
@login_required
def cleaning(start, end):
prob_forms = []
for pif in xrange(start, end+1):
pf = ProblemForm(request.form, title=session["problems"][pif][0])
pf.opts.choices = [(pr, pr) for pr in session["problems"][pif][1]]+[('<null>', '<null>')]
prob_forms.append(pf)
if request.method == "POST":
pass
return render_template("main/cleaning.html", forms=prob_forms, buttons=ControlButtons(),
start=start, end=end)
令人沮丧的是,这个 几乎 有效。发布表格时
request.form.lists() 包含:[('select_uinput', [u'7']), ('user_input', [u'', u'', u'', u'', u '', u'', u'', u'']), ('select_alias', [u'2']), ('alias_of', [u'', u'Dirty Jobs with Mike Rowe' , u'', u'', u'', u'', u'', u'']), ('opts', [u'天堂']), ('next', [你'下一个'])]。我可以用这个;其中一个复选框在第 7 个表单中被选中,另一个在第 2 个表单中被选中,在第 2 个表单中用户在 "alias_of" 框中键入 'Dirty Jobs with Mike Rowe',等等
问题出在名为 "opts" 的 RadioField 上。它似乎只保存用户按下的最后一个按钮。任何人都知道为什么会这样,或者我应该在哪里寻找更多信息?
这是模板,如果有用的话:
{% extends "layout.html" %}
{% block content %}
<form action="{{ url_for('main.cleaning', start=start, end=end) }}" method="POST" enctype="multipart/form-data">
{% for form in forms %}
{% set outloop = loop %}
<div class="well well-lg">
<h3><em>{{ form.title }}</em>?</h3>
<!-- Possible Master List entries -->
<div class="btn-group" id="opts_{{outloop.index}}" role="group" data-toggle="buttons" aria-label="...">
{% for opt in form.opts %}
{% if loop.first %}
<label class="btn btn-default active">
{% else %}
<label class="btn btn-default">
{% endif %}
{{ opt }} {{ opt.label.text }}
</label>
{% endfor %}
</div><br />
<!-- Alias input -->
<div class="row">
<div class="col-lg-6">
<div class="input-group">
<span class="input-group-addon">
{{ form.select_alias(value=outloop.index) }}
</span>
<span class="input-group-addon" id="basic-addon2">Alias of</span>
{{ form.alias_of(class_="form-control") }}
</div><!-- /input-group -->
</div><!-- /.col-lg-6 -->
</div> <!-- /row -->
<!-- END Alias input -->
<!-- New Entry input -->
<div class="row">
<div class="col-lg-6">
<div class="input-group">
<span class="input-group-addon">
{{ form.select_uinput(value=outloop.index) }}
</span>
<span class="input-group-addon" id="basic-addon2">New Entry</span>
{{ form.user_input(placeholder=form.title, class_="form-control") }}
</div><!-- /input-group -->
</div><!-- /.col-lg-6 -->
</div> <!-- /row -->
</div>
<!-- END Alias input -->
{% endfor %}
{{ buttons.back() }} {{ buttons.next() }} {{ buttons.save() }}
</form>
{% endblock %}
选项 1:给每个表单实例 its own prefix:
for pif in xrange(start, end+1):
pf = ProblemForm(request.form, title=session["problems"][pif][0], prefix='problem-%d' % pif)
# etc
选项 2:或者,如果您使用 FormFields 的 FieldList 想出封闭表单,WTForms 可以为您生成带前缀的表单。
class EnclosingForm(Form):
problems = FieldList(FormField(ProblemForm))
然后使用 append_entry 在循环中添加子表单:
form = EnclosingForm(request.form)
for i, pif in enumerate(xrange(start, end+1)):
if len(form.problems.entries) <= i:
form.problems.append_entry({'title': session["problems"][pif][0]})
# etc
好吧,我在网上、文档和源代码中四处寻找,但我对这个问题一无所知。所以我正在使用 wtforms 和 bootstrap 开发一个 Flask 项目,我需要在一个页面上多次显示相同的表单。具体来说,这种形式:
class ProblemForm(Form):
def __init__(self, formdata=None, obj=None, prefix='', title="", **kwargs):
super(self.__class__, self).__init__(formdata=None, obj=None, prefix='', **kwargs)
self.title = title
opts = RadioField("Possible Corrections")
alias_of = StringField("Alias of")
select_alias = BooleanField("select_alias")
user_input = StringField("New Entry")
select_uinput = BooleanField("select_uinput")
在控制器逻辑中(见下文)我发现我可以创建一个 ProblemForm 实例数组,并根据会话中已有的数据为每个 "Problem" 设置选项。
@blueprint.route("/clean/review/<int:start>-<int:end>", methods=["GET", "POST"])
@login_required
def cleaning(start, end):
prob_forms = []
for pif in xrange(start, end+1):
pf = ProblemForm(request.form, title=session["problems"][pif][0])
pf.opts.choices = [(pr, pr) for pr in session["problems"][pif][1]]+[('<null>', '<null>')]
prob_forms.append(pf)
if request.method == "POST":
pass
return render_template("main/cleaning.html", forms=prob_forms, buttons=ControlButtons(),
start=start, end=end)
令人沮丧的是,这个 几乎 有效。发布表格时 request.form.lists() 包含:[('select_uinput', [u'7']), ('user_input', [u'', u'', u'', u'', u '', u'', u'', u'']), ('select_alias', [u'2']), ('alias_of', [u'', u'Dirty Jobs with Mike Rowe' , u'', u'', u'', u'', u'', u'']), ('opts', [u'天堂']), ('next', [你'下一个'])]。我可以用这个;其中一个复选框在第 7 个表单中被选中,另一个在第 2 个表单中被选中,在第 2 个表单中用户在 "alias_of" 框中键入 'Dirty Jobs with Mike Rowe',等等
问题出在名为 "opts" 的 RadioField 上。它似乎只保存用户按下的最后一个按钮。任何人都知道为什么会这样,或者我应该在哪里寻找更多信息?
这是模板,如果有用的话:
{% extends "layout.html" %}
{% block content %}
<form action="{{ url_for('main.cleaning', start=start, end=end) }}" method="POST" enctype="multipart/form-data">
{% for form in forms %}
{% set outloop = loop %}
<div class="well well-lg">
<h3><em>{{ form.title }}</em>?</h3>
<!-- Possible Master List entries -->
<div class="btn-group" id="opts_{{outloop.index}}" role="group" data-toggle="buttons" aria-label="...">
{% for opt in form.opts %}
{% if loop.first %}
<label class="btn btn-default active">
{% else %}
<label class="btn btn-default">
{% endif %}
{{ opt }} {{ opt.label.text }}
</label>
{% endfor %}
</div><br />
<!-- Alias input -->
<div class="row">
<div class="col-lg-6">
<div class="input-group">
<span class="input-group-addon">
{{ form.select_alias(value=outloop.index) }}
</span>
<span class="input-group-addon" id="basic-addon2">Alias of</span>
{{ form.alias_of(class_="form-control") }}
</div><!-- /input-group -->
</div><!-- /.col-lg-6 -->
</div> <!-- /row -->
<!-- END Alias input -->
<!-- New Entry input -->
<div class="row">
<div class="col-lg-6">
<div class="input-group">
<span class="input-group-addon">
{{ form.select_uinput(value=outloop.index) }}
</span>
<span class="input-group-addon" id="basic-addon2">New Entry</span>
{{ form.user_input(placeholder=form.title, class_="form-control") }}
</div><!-- /input-group -->
</div><!-- /.col-lg-6 -->
</div> <!-- /row -->
</div>
<!-- END Alias input -->
{% endfor %}
{{ buttons.back() }} {{ buttons.next() }} {{ buttons.save() }}
</form>
{% endblock %}
选项 1:给每个表单实例 its own prefix:
for pif in xrange(start, end+1):
pf = ProblemForm(request.form, title=session["problems"][pif][0], prefix='problem-%d' % pif)
# etc
选项 2:或者,如果您使用 FormFields 的 FieldList 想出封闭表单,WTForms 可以为您生成带前缀的表单。
class EnclosingForm(Form):
problems = FieldList(FormField(ProblemForm))
然后使用 append_entry 在循环中添加子表单:
form = EnclosingForm(request.form)
for i, pif in enumerate(xrange(start, end+1)):
if len(form.problems.entries) <= i:
form.problems.append_entry({'title': session["problems"][pif][0]})
# etc