title: Flask + WTForms, dynamically generated list of fields
body: <p>I am making a Flask application that is essentially form-based and so I'm using WTForms and Flask-wtf.</p>
  
  <p>I am currently refactoring my code so my whole form uses WTForms and there is a very dynamic part of one of the forms that I am unable to implement using WTForms. I have no clue how to do it, my initial ideas didn't work, I can't find references or tutorials covering my problem and so this is why I ask for help.</p>
  
  <p>So, the form in question allows users to submit objects that consist of:</p>
  
  <ul>
  <li>A label (StringField, easy)</li>
  <li>A Description (TextAreaField, also easy; although I had trouble to make a default value work)</li>
  <li>A list of property of the form (predicate, object), where predicate is taken from a pre-built list and object can basically be anything but each predicate will generate a specific object (for instance, the predicate "related to" will expect another object (that comes from a dropdown list) and the predicate "resource" will expect a http link of some sort). This list can be empty.</li>
  </ul>
  
  <p>As you can guess I have trouble with the list. The way the code works right now, I get the label and description using wtforms, and the property list is generated using a config constant (that is used throughout the code so I only have one place to edit if I want to add new properties) and a dynamic menu in javascript that creates  (here, for predicates) fields, that I can then get using flask.request.form object in the view function. All the hidden fields for predicates have the same name attribute and all the hidden fields for objects have the same name attribute.</p>
  
  <p>Here is what the view of the form looks like, initialized with a few properties:</p>
  
  <p><a href="http://i.imgur.com/bfMG95s.png" rel="nofollow">http://i.imgur.com/bfMG95s.png</a></p>
  
  <p>Under the "Propriétés" label you have a dropdown to select the predicate, the second field is displayed or hidden depending on the selected predicate (can be a dropdown or a text field), and it is only when you click on "Ajouter propriété" ("Add property") that a new line is added in the tab below and the  fields are generated.</p>
  
  <p>I'd like not to have to change anything on this side because it works very well, makes the form very intuitive and is basically exactly what I want it to be from the user's end.</p>
  
  <p>This is what my custom Form looks like right now (it doesn't work and properties stays empty whatever the number of  fields I submit with the form):</p>
  
  <pre><code>class PropertyForm(Form):
      property_predicate = HiddenField(
          validators=[AnyOf(values=app.config["PROPERTY_LIST"].keys())]
      )
      property_object = HiddenField(
          validators=[DataRequired()]
      )
  
  class CategoryForm(Form):
      """
          Custom form class for creating a category with the absolute minimal
          attributes (label and description)
      """
      label = StringField(
          "Nom de la categorie (obligatoire)",
          validators=[DataRequired()]
      )
      description = TextAreaField(
          "Description de la categorie (obligatoire)",
          validators=[DataRequired()]
      )
      properties = FieldList(FormField(PropertyForm),validators=[Optional()])
  </code></pre>
  
  <p>And here is what I'd love to do in my views.py code (that I am currently refactoring):</p>
  
  <pre><code>def cat_editor():
      cat_form = CategoryForm()
      if request.method == "GET":
          # Do GET stuff and display the form
          return render_template("cateditor.html", form=cat_form, varlist=template_var_list)
      else if request.method == "POST":
          if cat_form.validate_on_submit():
              # Get values from form
              category_label = cat_form.label.data
              category_description = cat_form.description.data
              category_properties = cat_form.properties.data
              # Do POST stuff and compute things
              return redirect(url_for("index"))
          else:
              # form didn't validate so we return the form so the template can display the errors
              return render_template("cateditor.html", form=cat_form,
                                      template_var_list = template_var_list)
  </code></pre>
  
  <p>The basic structure works perfectly, it's just that damn dynamic list I can't get to work properly. </p>
  
  <p>Getting label and description from the WTForms CategoryForm instance works fine, but properties always return an empty list. Ideally I'd love to be able to get a list of the form [(predicate1, property1), (predicate2, object2) ... ] when calling cat_form.properties.data (this is why I have a FieldList of FormFields with two HiddenField in each) but I'd have no problem having to build such a list from two list as long as it's using WTForms. Any idea? Thanks a lot :)</p>