Dynamically adjusted forms inside FieldList

人走茶凉 提交于 2020-01-23 10:58:50

问题


I'm using Flask and Flask-WTF and I need to create a form that contains several blocks (subforms) of a similar structure (like a subform with one SelectField and one TextAreaField). As the docs suggest, I can use FormField together with FieldList to achieve this goal. However, I need to tweak my SelectField's dynamically (changing their choices at runtime according to values in the database). The docs now suggest

Note that the choices keyword is only evaluated once, so if you want to make a dynamic drop-down list, you’ll want to assign the choices list to the field after instantiation.

One can find an example of this approach here. However, FormField is accepting form_class, not an instance (at least, according to the docs), so it seems that these two recipes do not play well together.

Are there any other ideas?


回答1:


Okay, it's easier than I thought. You have to create those subforms with empty choices, create list of them and then adjust choices inside the list items.

class UserForm(wtforms.Form):
# must inherit from wtforms.Form, not flask-WTForms'
# see http://stackoverflow.com/questions/15649027/wtforms-csrf-flask-fieldlist
    first_name = StringField('First Name', [validators.DataRequired()])
    last_name = StringField('Last Name', [validators.DataRequired()])
    accepted_policy = BooleanField('Accept Policy')
    experience = SelectField('Experience', coerce=int)

class UsersForm(Form):
    users = FieldList(FormField(UserForm), min_entries=2)

@app.route('/', methods=['GET', 'POST'])
def hello_world():

    form = UsersForm(users=[{}, {}, {}])
    form.users[0].experience.choices=[(1, 'One'), (2, 'Two')]
    form.users[1].experience.choices = [(1, 'Uno'), (2, 'Du')]
    form.users[2].experience.choices = [(0, 'Zero')]
    return render_template("hello.html", form=form)

And here is a template:

{% macro render_field(field) %}
  <dt>{{ field.label }}
  <dd>{{ field(**kwargs)|safe }}
  {% if field.errors %}
    <ul class=errors>
    {% for error in field.errors %}
      <li>{{ error }}</li>
    {% endfor %}
    </ul>
  {% endif %}
  </dd>
{% endmacro %}

<form method=post>
  <dl>
      {{ form.hidden_tag()}}
      {%  for user_entry_form in form.users %}
          {{ user_entry_form.name }}
    {{ render_field(user_entry_form.first_name) }}
    {{ render_field(user_entry_form.last_name) }}
    {{ render_field(user_entry_form.experience) }}
      {%  endfor %}
  </dl>
  <p><input type=submit value=Go!>
</form>


来源:https://stackoverflow.com/questions/43159368/dynamically-adjusted-forms-inside-fieldlist

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!