如何通过wtforms将request.form存储到数据库,或解决sqlalchemy更新中的错误?

0 投票
1 回答
640 浏览
提问于 2025-04-18 09:12

这是接着这个问题来的:SQLalchemy/wtforms 更新问题 - 400 错误请求 我在使用 Flask 框架。

问题

当我提交表单时,弹出的提示信息显示“预测已添加”,但我查询数据库时发现没有任何变化??有没有人能帮我找出我哪里出错了?

我想实现的目标

用户可以查看他们的预测,并对当前的预测进行修改。如果没有新的预测,他们可以提交新的预测。

视图

# 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)\
                .outerjoin(User,Fixture_prediction.user_id == User.id)\
                .filter(Fixture_prediction.fixture_id==Fixture.id)\
                .filter(Fixture_prediction.user_id==user_id).all()
    data = {'predictions': prediction}
    form = PredictionListForm(data=MultiDict(data))
    if request.method == 'POST':
        if form.validate() == False:
            flash('A score is missing, please fill in all predictions')
            render_template('predictor.html', form=form)
        else:
            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)

想法

我感觉下面的代码只是提交了最开始就已经存在的内容,而不是表单请求的内容……

.update({'home_score':prediction.home_score.data\
                     ,'away_score':prediction.away_score.data})

模板

{% extends "base.html" %}

{% block content %}

  <h1>Predictions</h1>
  <p></p>
  <p>Please make your predictions here</p>
  <form action='' method='post'>
    {{form.predictions()}}
    <p><input type="submit" value="Submit Predictions"></p>
   </form>

{% endblock %}

模板 - 另一种选择

{% extends "base.html" %}

{% block content %}

  <h1>Predictions</h1>
  <p></p>
  <p>Please make your predictions here</p>
   <form action='' method='post'>
   <table>
       {%for form in form.predictions%}
        <tr>
            <td>{{form.fixture_id.data}}</td>
            <td>{{form.stage.data}}</td>
            <td>{{form.home_team.data}}</td>
            <td>{{form.home_score(size=1)}}</td>
            <td>{{form.away_score(size=1)}}</td>
            <td>{{form.away_team.data}}</td>
        </tr>
       {%endfor%}
   </table>
   <p><input type="submit" value="Submit Predictions"></p>
   </form>

{% endblock %}

模型

# Fixture prediction table
class Fixture_prediction(db.Model):
    __tablename__ = "fixture_prediction"
    id = db.Column('fixture_prediction_id',db.Integer, primary_key = True)
    fixture_id = db.Column('fixture_id',db.Integer, db.ForeignKey('fixture.fixture_id'))
    user_id = db.Column('user_id',db.Integer, db.ForeignKey('user.user_id'))
    home_score = db.Column('home_score',db.Integer)
    away_score = db.Column('away_score',db.Integer)

1 个回答

1

你的猜测是对的。你需要把 request.form 传给你的 PredictionListForm

form = PredictionListForm(request.form, data=MultiDict(data))

WTForms 首先会检查 request.form 里面的数据,只有在找不到数据的时候,它才会使用 data 这个参数。如果你不把 request.form 传进去,WTForms 就没有请求可以获取数据,所以它只能从你之前传入的 数据中获取。

撰写回答