Reputation: 128
I am working on a flask app with a few flask wtforms. When I get the forms they are never validated, yet the form errors are empty. What might be my issue?
One common issue I know I don't have is including the csrf_token. I included it and can see it's rendered in the html when my webpage loads. But none the less there is no validation
This is my html file being rendered
<div class="forms center">
<h1>Account Details</h1>
<h2>Update Email Address</h2>
<form id="update-email" action={{ url_for('crud.update_email') }} method="post">
{{ email_form.hidden_tag() }}
<div><input type="text" name="new-email" placeholder="new email address" value=""></div>
<div><input type="submit" name="submit" value="Update Email Address"></div>
</form>
<h2>Update Password</h2>
<form id="update-password" action={{ url_for('crud.update_password') }} method="post">
{{ password_form.hidden_tag() }}
<div><input type="password" name="old-password" placeholder="enter old password" id="old-password" value=""></div>
<div><input type="password" name="new-password" placeholder="enter new password" id="new-password" value=""></div>
<div><input type="password" name="retypepassword" placeholder="retype password" id="retypepassword" value=""></div>
<div><input type="submit" name="submit" id="submit" value="Update Password"></div>
</form>
</div>
And it is being rendered in this route
@views.route('/account-details', methods=['POST', 'GET'])
@login_required
def account_details():
email_form = UpdateEmailForm()
password_form = UpdatePasswordForm()
return render_template('account-details.html', email_form=email_form, password_form=password_form)
The submit of the update password form goes to here
@crud.route('/update-password', methods=['POST'])
def update_password():
form = UpdatePasswordForm()
old_password = request.form.get('old-password')
new_password = pbkdf2_sha256.hash(request.form.get('new-password'))
userid = session.get('userid')
user_dao = UserDao()
if form.validate_on_submit():
user_dao.update_password(userid, new_password)
return jsonify({"success": True})
return jsonify({"success": False})
Here is the form class I am using
from flask_wtf import FlaskForm
from wtforms import StringField, PasswordField, validators
from wtforms.validators import DataRequired, Email, EqualTo, Length, ValidationError
class UpdatePasswordForm(FlaskForm):
oldpassword = PasswordField('old-password', [DataRequired()])
newpassword = PasswordField('new-password', [DataRequired(), EqualTo('retypepassword'), Length(min=6)])
retypepassword = PasswordField('retypepassword', [DataRequired()])
Looking at the network tab in the browser it is sending the expected results in the post request and if I check on the back end it is receiving everything as expected. Unfortunately the form doesn't validate anyway and for this reason I expect it has to do with something I don't understand about wtforms
Thank you!
Upvotes: 0
Views: 708
Reputation: 4785
I don't believe the alternative answer to be correct. I have many FlaskForms where I do not pass the request.
Instead I think your error might be in your naming convention. Your Class field names are:
'oldpassword' 'newpassword' etc..
but your HTML element ids and names are:
'old-password' 'new-password'
I.e. the form does not know what to parse. Align your names..
Upvotes: 2
Reputation: 2050
In your POST, you need to pass the request data into the form:
form = UpdatePasswordForm(request.POST)
You won't need to get values from the request.form
and you can validate before doing updates:
@crud.route('/update-password', methods=['POST'])
def update_password():
form = UpdatePasswordForm(request.POST)
if form.validate_on_submit():
userid = session.get('userid')
user_dao = UserDao()
new_password = pbkdf2_sha256.hash(form.newpassword.data)
user_dao.update_password(userid, new_password)
return jsonify({"success": True})
return jsonify({"success": False})
Edit: I would highly recommend reading the WTForms crash course (and more) to get a good idea of what WTForms can do - it's very useful.
Upvotes: 1