1
votes

I'm using flask wtforms with input validation. Everything's working fine, except with validation failure my ValidationError message is not getting displayed to the user...

from flask_wtf import FlaskForm
from wtforms import StringField, SubmitField, PasswordField, ValidationError # URLField, EmailField
from wtforms.validators import DataRequired, Email, EqualTo

class SignupForm(FlaskForm):
    name = StringField("Name:", validators=[DataRequired()])
    email = StringField("Email:", validators=[DataRequired(), Email()])
    password = PasswordField("Password:", validators=[DataRequired(), EqualTo('pass_confirm', message='Passwords must match')])
    pass_confirm = PasswordField("Confirm:", validators=[DataRequired()])
    submit = SubmitField("Create Account")

    def validate_email(self, field):
        if User.query.filter_by(email=field.data).first():
            raise ValidationError('Your email has already been registered.')

    def validate_name(self, field):
        if User.query.filter_by(name=field.data).first():
            raise ValidationError('This username is taken.')

and in my view:

@users.route('/signup', methods=['GET','POST'])
def signup():
    form = SignupForm()

    if form.validate_on_submit():
        url = form.name.data # todo: generate unique url
        user = User(name=form.name.data,
                    url=url,
                    email = form.email.data,
                    password = form.password.data)
        db.session.add(user)
        db.session.commit()

        return redirect(url_for('users.login'))

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

and this is the template:

<div class="jumbotron">
  <h1>Sign up Page</h1>
  <p>Please fill out the form</p>
  <form method="POST">
    {{ form.hidden_tag() }}
    <div class="form-group">
      {{ form.name.label(class='form-group') }}
      {{ form.name(class='form-control') }}
    </div>

    <div class="form-group">
      {{ form.email.label(class='form-group') }}
      {{ form.email(class='form-control') }}
    </div>

    <div class="form-group">
      {{ form.password.label(class='form-group') }}
      {{ form.password(class='form-control') }}
    </div>

    <div class="form-group">
      {{ form.pass_confirm.label(class='form-group') }}
      {{ form.pass_confirm(class='form-control') }}
    </div>

      {{ form.submit(class='btn btn-primary') }}
  </form>

</div>

Upon submitting an invalid form (either invalid email or name) the form simply returns blank, without indicating what the user did wrong. How can I display those validationerrors to the user? Much appreciated!

2
that solves, it - thanks so much! - Muriel
I'm glad I could help. But the moderators will probably close your question as a duplicate. - VPfB
that's fine - better to have only one question with many votes than duplicates. Do I need to upvote our answer? plus can I give you the bounty somehow? - Muriel
I don't think I deserve a bounty for writng a short comment. Don't worry, enjoy SO. - VPfB

2 Answers

1
votes

form must get some data

@users.route('/signup', methods=['GET','POST'])
def signup():
    form = SignupForm(request.form)

or

@users.route('/signup', methods=['GET','POST'])
def signup():
    form = SignupForm(request.json)
0
votes

I believe you are importing ValidationError incorrectly Try this importing it from wtforms.validators like this->

from flask_wtf import FlaskForm
from wtforms import StringField, SubmitField, PasswordField # URLField, EmailField
from wtforms.validators import DataRequired, Email, EqualTo, ValidationError

In addition to this, you can add flash messages to your screen from your routes code such as this.

from flask import flash
if form.validate_on_submit():
    flash(f'Info was saved to the database for user {form.name.data}', success)
else:
    flash('Failed to save to database', 'danger')