Skip to main content
 首页 » 编程设计

python之WTForms 向 SQLAlchemy 提交动态字段

2025年05月04日7youxin

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

View .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 
    ) 

设置.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 %} 

谢谢

请您参考如下方法:

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

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

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