2013-06-17 2 views
2

Я создаю ряд полей формы динамически из строк базы данных, каждое поле будет иметь свою собственную форму. Когда будет отправлена ​​форма, она обновит строку в базе данных. У меня проблема в том, как я могу сопоставить представленную форму с соответствующей строкой? Все поля формы имеют одно и то же имя «shared», но это должно быть нормально, так как каждое поле имеет свою собственную форму.WTForms отправляет динамические поля в SQLAlchemy

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

Вы должны создать одну форму вместо нескольких (одна форма == один запрос).

Например, вы можете создать форму класса dynamicaly с именами 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"/> 
+0

Большое спасибо, что нашли время, чтобы ответить на tbicr. Начиная с публикации, я работал над немного другим решением, используя подкласс формы. В идеале я хотел бы, чтобы это решение работало, поскольку в моей голове стало яснее. Если мне не повезет, я попробую ваше предложение. Еще раз спасибо. – bobwal

+0

Вы можете отправить одну html-форму без js за один раз, поэтому для ее отправки из ваших полей должны быть уникальные имена 'shared_ ' или быть многозначным значением ''. В одной форме html вы можете просто использовать поля с несколькими значениями, но вы не можете получить идентификаторы в этом случае (реально могут быть только эти идентификаторы значений или содержать идентификаторы). Для этого решения лучше использовать JS и AJAX, но без него я не вижу другого решения, а затем уникальных имен полей. Однако будет интересно увидеть ваше решение, потому что в моем проекте для статической html-формы у меня есть проблема. – tbicr

Смежные вопросы