WTForms fieldlist 'StringField' object is

2019-08-25 02:20发布

问题:

I'm getting this error only when the field is defined in a form that contains other fields- but when its defined in a it's own form, this error is not generated and it works.

Firstly I will show what works successfully:

class TrackForm(Form):
    name = StringField('Name')
    start = StringField('Start')
    end = StringField('End')

class Merge(Form):
    item_description = FieldList(FormField(TrackForm), min_entries=1, max_entries=32)

view.py

@app.route('/test', methods=['GET', 'POST'])
def test():
        form=Merge()
        return render_template(
        'test.html', title='test', form=form)

templates/test.html:

<form method="POST" >
  {{ form.hidden_tag() }}
  <table id="fruitTable" class="table">
    <tr><td><h3>Tracks</h3></td></tr>
    {% set counter = 0 %}
    {% for track in form.item_description %}
      <tr>
        {{ track.hidden_tag() }}
        {% set counter = counter + 1%}
        {% for field in track if field.widget.input_type != 'hidden' %}
          {{ render_field_oneline(field) }}
        {% endfor %}
        {% if counter > 1 %}
          <td>
            <button class="btn" type="button" onClick="removeTrack()"><i class="icon-black icon-minus"></i></button>
          </td>
        {% endif  %}
      </tr>
    {% endfor %}
      <tr><td></td><td><button class="btn" type="button" onClick="addTrack()"><i class="icon-black icon-plus"></i></button></td></tr>
  </table>
<input class="btn btn-primary" style="margin-left:300px;"type="submit" value="Submit" />
</form>
<script src="static/js/populateselect.js" type="text/javascript"></script>
{% endblock %}

However, when I try and move the item_description field to a live form that contains other fields, I run in to the problem. Below is what doesn't work and generates the error:

class TrackForm(Form):
    name = StringField('Name')
    start = StringField('Start')
    end = StringField('End')

class SendForm(Form):
        item_description = FieldList(FormField(TrackForm), min_entries=1, max_entries=32)
        rai_number = StringField('rai_number', validators=[DataRequired(), Regexp('^RA[0-9]{5}$', message='Asset number must contain 7 characters- "RA" followed by 5 digits')])
        spool_number = StringField('spool_number', validators=[DataRequired(), Regexp('^[a-zA-Z0-9]{1,19}$', message='You have entered too many numbers/digits')], filters = [lambda x: x or None])
        carrier_format = SelectField('carrier_format', choices=carrier_choices, validators=[DataRequired()], filters = [lambda x: x or None])
        physical_location = SelectField('physical_location', choices=physical_location_choices, validators=[DataRequired()], filters = [lambda x: x or None])
        programme_sub_category = SelectField('programme_sub_category', choices=sub_category_choices, filters = [lambda x: x or None])
        programme_category = SelectField('programme_category', choices=[('',''),('Live Music', 'Live Music'), ('ROT', 'ROT'), ('Unpublished', 'Unpublished'), ('Pre-Rec', 'Pre-Rec'), ('Interview', 'Interview')], filters = [lambda x: x or None])
        programme_title = StringField('programme_title', filters = [lambda x: x or None])

views.py

@app.route('/test', methods=['GET', 'POST'])
def test():
        form=SendForm()
        return render_template(
        'test.html', title='test', form=form)

The template remains the same.

This is the error:

{% for track in form.item_description %}
[Thu Aug 24 16:55:20.142971 2017] [:error] [pid 56022] [remote 10.100.48.53:124] TypeError: 'StringField' object is not iterable

I don't understand why moving the item_description field to a separate form creates this issue?