【问题标题】:WTForms submitting dynamic fields to SQLAlchemyWTForms 向 SQLAlchemy 提交动态字段
【发布时间】:2013-06-17 15:39:23
【问题描述】:

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

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 %}

谢谢

【问题讨论】:

    标签: python sqlalchemy flask wtforms flask-wtforms


    【解决方案1】:

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

    例如,您可以使用shared_&lt;CAR_ID&gt; 字段名称动态创建表单类:

    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"/>
    

    【讨论】:

    • 非常感谢您花时间回答 tbicr。自发布以来,我一直在使用表单子类研究稍微不同的解决方案。理想情况下,我想让这个解决方案发挥作用,因为它在我的脑海中更加清晰。如果我没有运气,我会试试你的建议。再次感谢。
    • 您可以一次发送一个不带js的html表单,因此从您的字段发送一个必须具有唯一名称shared_&lt;CAR_ID&gt;或多值&lt;shared[]&gt;。使用单个 html 表单,您可以只使用多值字段,但在这种情况下您无法获取 ID(只有在此值 ID 或包含 ID 时才能获取)。对于这个解决方案,最好使用 JS 和 AJAX,但没有它,我看不到其他解决方案,然后是唯一的字段名称。但是,看到您的解决方案会很有趣,因为在我的静态 html 表单项目中我遇到了一些问题。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-07-02
    • 1970-01-01
    • 2017-10-07
    • 2015-04-07
    • 2015-03-05
    • 2012-10-02
    • 1970-01-01
    相关资源
    最近更新 更多