Вопрос

I'm trying to find better solution for this. My solution now is very awkward (but works), because if i wanted like 20 selectfields... u can imagine how horrible and long will template look like etc...
so basically what i'm asking is, if some SelectFieldArray object exists in WTForm? i didnt find in documentation.
So here's my awkward solution for now:
In my view method i do this:

form = ResultForm()

if form.validate_on_submit():
    print form.f1.data
    print form.f2.data

my template:

{% extends "base.html" %}
{% block body %} 
<form method="post">
    {{ form.hidden_tag() }}
    <p>
        <label for="title">
            {{form.f1.label}}
        </label><br/>
        {{form.f1}}
         <label for="title">
            {{form.f2.label}}
        </label><br/>
        {{form.f2}}

        {% if form.f1.errors %}
            <ul class="errors">
                {% for error in form.f1.errors %}
                <li>{{ error }}</li>
                {% endfor %}
            </ul>
        {% endif %}
        {% if form.f2.errors %}
            <ul class="errors">
                {% for error in form.f1.errors %}
                <li>{{ error }}</li>
                {% endfor %}
            </ul>
        {% endif %}
    </p>
    <input type="submit" value="Go">
</form>
{% endblock %}

my WTForm class:

from flask.ext.wtf import Form
from wtforms import TextField, PasswordField,SelectField,validators
from wtforms.validators import Required
class ResultForm(Form):
f1 = SelectField(u'f1',
            coerce=int,
            validators=[validators.optional()],
            choices=[(1, 'A'),(2, 'B'),(3, 'C'),(4, 'D'),(5, 'E'),(6, 'FX'),(7, 'na')])
f2 = SelectField(u'f2',
            coerce=int,
            validators=[validators.optional()],
            choices=[(1, 'A'),(2, 'B'),(3, 'C'),(4, 'D'),(5, 'E'),(6, 'FX'),(7, 'na')])
Это было полезно?

Решение

To have one field repeated you can use wtforms.fields.FieldList (see the documentation about Field Closures):

class ResultForm2(BaseForm):
    selects = FieldList(SelectField(u'Select', coerce=int,
                                    validators=[validators.optional()],
                                    choices=[(1, 'A'), (2, 'B'), (3, 'C'),
                                             (4, 'D'), (5, 'E'), (6, 'FX'),
                                             (7, 'na')]), min_entries=2)

That produces two select inputs with names "select-0" and "selects-1" (because of min_entries set to two). Both have identical data though.

You can also create forms dynamically (see documentation about Dynamic Form Composition), for example:

def my_dynamic_form(select_field_count=20):
    class F(MyBaseForm):
        pass
    for i in range(select_field_count):
        setattr(F, 'f%d' % i, SelectField('F%d' % i, coerce=int,
                                        validators=[validators.optional()],
                                        choices=[(1, 'A'), (2, 'B'), (3, 'C'),
                                                 (4, 'D'), (5, 'E'), (6, 'FX'),
                                                 (7, 'na')]))
    return F

This way the form can be constructed completely dynamic, for example SelectFields could have different choices.

Другие советы

@oliverdm i cant even make comment on your response without 50reputation... n/c

what i'm trying to do is this:

<form action="">
<select name="" id=""></select>
<select name="" id=""></select>
<select name="" id=""></select>
<select name="" id=""></select>
<select name="" id=""></select>
<select name="" id=""></select>
 </form>

without doing this...

class ResultForm(Form):
  f1 = SelectField(u'f1',...
  f2 = SelectField(u'f2',...
  f3 = SelectField(u'f3',...
  f4 = SelectField(u'f4',...
  f5 = SelectField(u'f5',...

and then with view method do something like form[i].data ... or something....
Is this what your code example does?

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top