问题
What I'm trying to do
Instead of using form.predictions() I've tried to separate it out so I can style it better, although it doesn't work when I submit the predictions apart from the first prediction..i.e doesn't update it apart from the first one.
I don't really want to write them all out hence the for loop and loop.index
Issue
Say if update one row of scores, it does not update the db, although I get a flash message saying I have. Strangely only row 1 works and the others dont.
views
# Predictor - User makes predictions and saves/
@app.route('/predictor/',methods=['GET','POST'])
@login_required
def predictions():
user_id = g.user.id
# retrieve predictions
prediction= db.session.query(Fixture_prediction,\
Fixture_prediction.fixture_id,Fixture.stage,\
Fixture.home_team,Fixture_prediction.home_score,\
Fixture_prediction.away_score,Fixture.away_team)\
.outerjoin(Fixture,Fixture.id==Fixture_prediction.fixture_id)\
.filter(Fixture_prediction.fixture_id==Fixture.id)\
.filter(Fixture_prediction.user_id==user_id).all()
data = {'predictions': prediction}
form = PredictionListForm(request.form,data=MultiDict(data))
if request.method == 'POST':
for prediction in form.predictions:
store=db.session.query(Fixture_prediction) \
.filter(Fixture_prediction.user_id==user_id) \
.filter(Fixture_prediction.fixture_id==prediction.fixture_id.data)\
.update({'home_score':prediction.home_score.data\
,'away_score':prediction.away_score.data})
db.session.commit()
flash('Prediction added')
return redirect(url_for('predictions'))
# display current predictions
elif request.method == 'GET':
return render_template('predictor.html', form=form)
template
<form action='' method='post'>
<table>
<tr>
<th>Fixture Id</th>
<th>Stage</th>
<th>Home Team</th>
<th>Home Score</th>
<th>Away Score</th>
<th>Away Team</th>
</tr>
{%for prediction in form.predictions%}
<tr>
<td><input name="predictions-{{loop.index0}}-fixture_id" type="text" value={{prediction.fixture_id.data}}></td>
<td><input name="predictions-{{loop.index0}}-stage" type="text" value="{{prediction.stage.data}}"></td>
<td><input name="predictions-{{loop.index0}}-home_team" type="text" value={{prediction.home_team.data}}></td>
<td><input name="predictions-{{loop.index0}}-home_score" type="text" value={{prediction.home_score.data}}></td>
<td><input name="predictions-{{loop.index0}}-away_score" type="text" value={{prediction.away_score.data}}></td>
<td><input name="predictions-{{loop.index0}}-away_team" type="text" value={{prediction.away_team.data}}></td>
</tr>
{%endfor%}
</table>
<p><input type="submit" value="Submit Predictions"></p>
</form>
回答1:
I believe the problem is in this block of code:
if request.method == 'POST':
for prediction in form.predictions:
store=db.session.query(Fixture_prediction) \
.filter(Fixture_prediction.user_id==user_id) \
.filter(Fixture_prediction.fixture_id==prediction.fixture_id.data)\
.update({'home_score':prediction.home_score.data\
,'away_score':prediction.away_score.data})
db.session.commit()
flash('Prediction added')
return redirect(url_for('predictions'))
The problem is after the first iteration of your for loop, you commit your changes, flash a message and redirect. These three statements need to be outside the for loop like below:
if request.method == 'POST':
for prediction in form.predictions:
store=db.session.query(Fixture_prediction) \
.filter(Fixture_prediction.user_id==user_id) \
.filter(Fixture_prediction.fixture_id==prediction.fixture_id.data)\
.update({'home_score':prediction.home_score.data\
,'away_score':prediction.away_score.data})
db.session.commit()
flash('Prediction added')
return redirect(url_for('predictions'))
来源:https://stackoverflow.com/questions/24160335/how-do-i-correctly-submit-results-from-a-wtformusing-jinja-with-a-python-flask