我看到相同的奇怪行为发布到Filling WTForms FormField FieldList with data results in HTML in fields,其中我的原始字段是使用HTML而不是默认值呈现的。在另一个示例中,基本上是在单个FormField上对FieldList进行了一层深层堆叠。在我的情况下,我正在FormField上的FieldList上创建FieldList的2D结构。我不知道我在哪里。
app.py
import os
from flask import Flask, redirect, render_template, request, send_file, url_for
from flask_wtf import FlaskForm
from flask_wtf.csrf import CSRFProtect
from wtforms import FieldList, FormField, RadioField, TextAreaField, validators
app = Flask(__name__)
csrf = CSRFProtect(app)
SECRET_KEY = os.urandom(32)
app.config['SECRET_KEY'] = SECRET_KEY
#region FORMS
class TestCaseItem(FlaskForm) :
pass_fail_radio = RadioField( '' , choices=[('Pass','Pass'), ('Fail','Fail')] , default='Pass' , validators=[validators.DataRequired()] )
failure_message = TextAreaField(default='')
class TestCaseForm(FlaskForm) :
test_items = FieldList( FormField( TestCaseItem ))
class ManualTestForm(FlaskForm):
test_cases = FieldList( FormField(TestCaseForm))
#endregion
@app.route("/" , methods = ['POST', 'GET'])
def index():
form = ManualTestForm()
test_cases = ["test case {}".format(i) for i in range(5)]
devices = ["device {}".format(i) for i in range(3)]
# Expand the field list for each test case
for tc in test_cases :
tcf = TestCaseForm()
# expand its field list for each test device
for device in devices :
tci = TestCaseItem()
tci.failure_message = 'abc'
tcf.test_items.append_entry( tci )
form.test_cases.append_entry( tcf )
return render_template('test_template.html', form=form, test_cases=test_cases, devices=devices )
if __name__ == "__main__" :
app.run(debug=True, port=5001) # http://127.0.0.1:5001
templates / test_template.html
<html>
<head>
</head>
<body>
<h1>Manual Test Submission</h1>
<h2>Test Suite</h2>
<form method="post">
{{ form.csrf_token }}
<!--TEST CASES-->
<table>
<tr>
<th>Test Case ID</th>
{% for test_item in form.test_cases[0].test_items %}
{% set device = devices[loop.index0] %}
<th>TC Status: {{device}}</th>
<th>TC Input: {{device}}</th>{% endfor %}
</tr>
{% for test_case in form.test_cases %}
{{test_case.hidden_tag()}}
<tr>
<td>{{ test_cases[ loop.index0 ]}}</td>
{% for test_item in test_case.test_items %}
<td>{{ test_item.pass_fail_radio }}</td>
<td>{{ test_item.failure_message }}</td>{% endfor %}
</tr>{% endfor %}
</table>
</form>
</body>
</html>
答案 0 :(得分:1)
以通常的方式在视图中设置所有字段值,但在模板中,将.data
属性用于属于嵌套表单的字段:
{% for test_case in form.test_cases %}
{{ test_case.hidden_tag() }}
{{ test_cases[loop.index0] }}
{% for test_item in test_case.test_items %}
{{ test_item.pass_fail_radio.data }}
{{ test_item.failure_message.data }}
{% endfor %}
{% endfor %}
关于它的价值,在处理嵌套的FieldList时还有另一个陷阱:如果以逻辑方式构造表单,由于id
和name
属性的名称将不完全命名空间.append_entry()
的工作方式。结果,期望值将不会发布,并且验证也将中断。
损坏:
form = RecipientsForm()
for proprietor in proprietors:
proprietor_form = ProprietorForm()
# Set proprietor name in hidden input field.
proprietor_form.prop_name = proprietor['name']
# populate and append addresses to proprietor form.
for address in proprietor['addresses']:
address_form = AddressForm()
address_form.address = address['address']
address_form.address_type = address['type']
proprietor_form.addresses.append_entry(address_form)
form.proprietors.append_entry(proprietor_form)
作品:
form = RecipientsForm()
proprietors = proprietor_api_call()
# Populate and append proprietors to Recipients form.
for idx, proprietor in enumerate(proprietors):
proprietor_form = ProprietorForm()
proprietor_form.prop_name = proprietor['name']
form.proprietors.append_entry(proprietor_form)
# Populate and append addresses to Proprietor form.
for address in proprietor['addresses']:
address_form = AddressForm()
address_form.address = address['address']
address_form.address_type = address['type']
form.proprietors[idx].addresses.append_entry(address_form)