I'm seeing the same strange behavior posted to Filling WTForms FormField FieldList with data results in HTML in fields where my raw fields are rendering with HTML rather than their default values. In that other example there's basically a one layer deep stacking of a FieldList over a single FormField. In my case I'm creating a 2D structure of a FieldList over a FieldList over a FormField. I can't figure out where I'm off here.
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>