Как я могу создать форму из списка моделей с помощью WTForms?

StackOverflow https://stackoverflow.com//questions/24018629

Вопрос

У меня есть список Prediction модели.Я хочу привязать их к форме и разрешить использование обратной связи.Как я могу структурировать свою форму, чтобы сообщение связывало оценку дома/в гостях с Prediction модели id поле для каждого элемента, который я привязываю к форме?

вид

@app.route('/predictor/',methods=['GET','POST'])
@login_required
def predictions():    
    user_id = g.user.id
    prediction= # retrieve prediction
    if request.method == 'POST':
        if form.validate() == False:
            flash('A score is missing, please fill in all predictions')
            render_template('predictor.html', prediction=prediction, form=form)
        else:
            for pred in prediction:
                # store my prediction
            flash('Prediction added')
            return redirect(url_for("predictions"))    
    # display current predictions
    elif request.method == 'GET':
        return render_template('predictor.html', prediction=prediction, form=form)

форма

class PredictionForm(WTForm):
    id = fields.IntegerField(validators=[validators.required()], widget=HiddenInput())
    home_score = fields.TextField(validators=[validators.required()])
    away_score = fields.TextField(validators=[validators.required()])

шаблон

  <form action="" method="post">
    {{form.hidden_tag()}}
    <table>
        {% for pred in prediction %}
        <tr>
            <td>{{pred.id}}</td>
            <td>{{form.home_score(size=1)}}</td>
            <td>{{form.away_score(size=1)}}</td>               
        </tr>
        {% endfor %}
    </table>
    <p><input type="submit" value="Submit Predictions"></p>
   </form>

Я не могу правильно привязать свои данные к POST.Требуемые валидаторы постоянно терпят неудачу, потому что в почтовых данных отсутствуют все Необходимый поля.

Это было полезно?

Решение

Вам нужна подчиненная форма, которая будет привязана к элементам в списке прогнозов:

Описанная вами форма позволит вам отправить только один прогноз.Кажется, существует несоответствие, потому что вы связываете итерацию прогнозов, и может показаться, что вам нужен прогноз дома и на выезде для каждого.Фактически, в его нынешнем виде он никогда не будет отправлять ответные сообщения. id поле.Это всегда приведет к сбою проверки формы.Я думаю, что вам нужен список подформ.Вот так:

# Flask's form inherits from wtforms.ext.SecureForm by default
# this is the WTForm base form. 
From wtforms import Form as WTForm

# Never render this form publicly because it won't have a csrf_token
class PredictionForm(WTForm):
    id = fields.IntegerField(validators=[validators.required()], widget=HiddenInput())
    home_score = fields.TextField(validators=[validators.required()])
    away_score = fields.TextField(validators=[validators.required()])

class PredictionListForm(Form):
    predictions = FieldList(FormField(PredictionForm))

Ваше представление должно будет вернуть что-то вроде:

predictions = # get your iterable of predictions from the database
from werkzeug.datastructures import MultiDict
data = {'predictions': predictions}
form = PredictionListForm(data=MultiDict(data))

return render_template('predictor.html', form=form)

Ваша форма должна будет измениться на что-то вроде этого:

<form action='my-action' method='post'>
    {{ form.hidden_tag() }}
    {{ form.predictions() }}
</form>

Теперь это напечатает <ul> с <li> за элемент, потому что это то, что делает FieldList.Я оставлю вам возможность стилизовать его и придать ему табличную форму.Это может быть немного сложно, но это не невозможно.

При отправке POST вы получите словарь formdata со счетом дома и на выезде для каждого прогноза. id.Затем вы можете связать эти прогнозы обратно в свой SQLАлхимия модель.

[{'id': 1, 'home': 7, 'away': 2}, {'id': 2, 'home': 3, 'away': 12}]

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

 {% for key in di_RAA %}
   <tr>
   <td><form id="Run" action="{{ url_for('index') }}" method="post">
        <input type="submit" class="btn" value="TEST" name="RUN_{{key}}"> 
   </form></td>
   </tr>
 {% endfor %}

Он предоставляет другое простое решение для нескольких кнопок.FieldList хорош, сложно получить имя каждой кнопки и функцию триггера.

from wtforms import fields
from wtforms.fields import FieldList, FormField
from wtforms import validators

Несколько советов. Возможно, стоит добавить импорт и убрать сообщение об ошибке импорта.

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