SQLalchemy/wtforms update issue - 400 bad request

穿精又带淫゛_ 提交于 2019-12-12 06:27:58

问题


What I'm trying to do is, once the user submits all the results I want it to update the Fixture_prediction model according to my filters. Although what I get is 400 bad request. The log doesnt tell me enough to know whats going wrong. Any ideas?

I think its to do with the tuple data submitted through the form...

The form displays fine its just when I submit the form it goes straight to a bad request.

my error

Bad Request

The browser (or proxy) sent a request that this server could not understand.

What I have currently:

views

@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 pred in prediction:
            store=Fixture_prediction.query\
                            .filter_by(user_id=user_id)\
                            .filter_by(fixture_id=request.form['fixture_id'])\
                            .update({'home_score':request.form['home_score']\
                                    ,'away_score':request.form['away_score']})
            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

{% 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 %}

forms

class PredictionForm(WTForm):
    fixture_id = fields.IntegerField(validators=[validators.required()])
    stage = fields.TextField(validators=[validators.required()])
    home_team = fields.TextField(validators=[validators.required()])
    home_score = fields.IntegerField(validators=[validators.required()])
    away_score = fields.IntegerField(validators=[validators.required()])
    away_team = fields.TextField(validators=[validators.required()])

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

回答1:


The problem is that there is no field fixture_id in request.form. This results in a KeyError being raised by the underlying MultiDict, which is translated into a 400 by Flask.

The reason there is no fixture_id is because you are using the field enclosures FieldList and FormField both of which alter the names you provide to WTForms to avoid collisions.

The fix is to simply use the form instance that you have to access the data (as WTForms has already mapped it for you):

# in your else clause
for prediction in form.predictions:
    store = Fixture_prediction.query \
                              .filter_by(user_id=user_id) \
                              .filter_by(fixture_id=prediction.fixture_id.data)
    # etc. 



回答2:


According to the flask docs, a 400 occurs when:

What happens if the key does not exist in the form attribute? In that case a special KeyError is raised. You can catch it like a standard KeyError but if you don’t do that, a HTTP 400 Bad Request error page is shown instead. So for many situations you don’t have to deal with that problem.

It sounds like the wtform is accessing a key that is not in the multidict, raising a keyerror. To test this, wrap the validate call with a try/except. (I think, I'd assume this is where the keyerror occurs). If you catch the exception, you'll have your answer.



来源:https://stackoverflow.com/questions/24119873/sqlalchemy-wtforms-update-issue-400-bad-request

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!