WTForms向SQLAlchemy提交动态字段

时间:2013-06-17 15:39:24

标签: python sqlalchemy flask wtforms flask-wtforms

我正在从数据库行动态创建一系列表单字段,每个字段都有自己的表单。提交表单时,它将更新数据库中的一行。我遇到的问题是如何将提交的表格与相关行匹配?所有表单字段都具有相同的名称“共享”,但这应该没问题,因为每个字段都有自己的表单。

views.py

def setting(nickname):
    user = User.query.filter_by(nickname = nickname).first()
    cars = user.cars.all()

    form_list = []
    for car in cars:
        class F(Form):
            pass
        setattr(F, 'shared', TextField(default=car.shared, label = car.carname))
        form = F(request.form, obj = car)
        form_list.append(form)

    if form.validate_on_submit():
        flash(request.form)
        flash(form.shared.data)

    return render_template('settings.html',
        user = user,
        form_list = form_list
    )

settings.html

{% for field in form_list %}
<form action="" method="post" name="share">
    {{ field.shared.label }} - {{ field.shared }}
    <input type="submit" value="share/make private"/>
</form>
{% endfor %}

由于

1 个答案:

答案 0 :(得分:1)

您必须创建一个表单而不是几个(一个表单==一个请求)。

例如,您可以使用shared_<CAR_ID>字段名称创建表格类dynamicaly:

def create_cars_form_class(cars):
    form_fields = {}
    for car in cars:
        field_id = 'shared_{}'.format(car.id)
        form_fields[field_id] = TextField(label=car.carname,
                                          default=car.shared)
    return type('CarsForm', (Form,), form_fields)

def settings(nickname):
    user = User.query.filter_by(nickname = nickname).first()
    cars = user.cars.all()
    CarsForm = create_cars_form_class(cars)

    if request.method == 'POST':
        shareform = CarsForm(request.form)
        if shareform.validate():
            for name, value in shareform.data.items():
                if not name.stratswith('shared_'):
                    continue
                car_id = name.lstrip('shared_')

                # update shared there
                update_car_shared(car_id, value)
    else:
        sharefrom = CarsForm()

    return render_template('settings.html',
        user = user,
        shareform = shareform,
    )

{% for name, field in shareform._fields.items() %}
    {% if name.startswith('shared_') %}
        {{ field.label }}: {{ field }}<br/>
    {% endif %}
{% endfor %}
<input type="submit" value="share/private"/>