Reputation: 5584
I'm trying to make a form to populate a calendar. The calendar can be five or seven days long, and I'd like to pass the number of days as an argument to the form. My form is defined like so:
class LoadForecastForm(Form):
def __init__(self, n_days, *args, **kwargs):
self.n_days = n_days
super(LoadForecastForm, self).__init__(*args, **kwargs)
self.day_values = FieldList(SelectField('Day Values', coerce=str, choices=[('low', 'Low'), ('medium', 'Medium'), ('high', 'High'), ('holiday', 'Holiday')]), min_entries=n_days, max_entries=n_days)
self.send = SubmitField('Send Calendar')
It's rendered like so:
<form role="form" action="" method="POST">
{{ form.hidden_tag() }}
<div class="form-group row">
{% for field in form.day_values %}
<div class="col-sm-2">
<div class="form-group{% if field.errors %} error {% endif %}">
{% if label %}
{{ field.label }}
{% endif %}
{{ field(**kwargs) }}
{% for error in field.errors %}
<span class="help-inline">[{{error}}]</span><br>
{% endfor %}
</div>
</div>
{% endfor %}
</div>
{{ form.send }}
The form page is failing to render; the traceback ends with:
File "project/populate_schedule.tpl.html", line 25, in block "page_content"
{% for field in day_values %}
TypeError: 'UnboundField' object is not iterable
n_days
used to be hardcoded, and the fields were defined as class variables with no __init__()
function, and there were no errors. How do I correctly define the field programmatically? I am using Python 2.7.
Upvotes: 0
Views: 914
Reputation: 55670
You need to leave the field definitions in the class body, otherwise they won't be picked up with the class is constructed. When the form instance is being initialised you can apply the max/min entries values to the fieldlist.
class F(Form):
day_values = FieldList(SelectField('Day Values',
coerce=str,
choices=[('low', 'Low'), ('medium', 'Medium'),
('high', 'High'), ('holiday', 'Holiday')]))
send = SubmitField('Send Calendar')
def __init__(self, *args, **kwargs):
ndays = kwargs.pop('n_days')
super(F, self).__init__(*args, **kwargs)
self.day_values.min_entries = n_days
self.day_values.max_entries = n_days
Test:
n_days = 4
f = F(n_days=n_days)
for x in range(n_days):
f.day_values.append_entry()
for field in f.day_values:
print field()
print
Output:
<select id="day_values-0" name="day_values-0"><option value="low">Low</option><option value="medium">Medium</option><option value="high">High</option><option value="holiday">Holiday</option></select>
<select id="day_values-1" name="day_values-1"><option value="low">Low</option><option value="medium">Medium</option><option value="high">High</option><option value="holiday">Holiday</option></select>
<select id="day_values-2" name="day_values-2"><option value="low">Low</option><option value="medium">Medium</option><option value="high">High</option><option value="holiday">Holiday</option></select>
<select id="day_values-3" name="day_values-3"><option value="low">Low</option><option value="medium">Medium</option><option value="high">High</option><option value="holiday">Holiday</option></select>
Upvotes: 2