wtforms raise a validation error after the form is validated

11,606

Solution 1

I solved it by manually appending errors to the field i wanted.

It looks like that

try:

    [...]
except StripeError as e:
    form.payment.errors.append('the error message')
else:
    db.session.commit()
    return redirect(url_for('home'))

Solution 2

on your wtform itself you can add a method prefixed with validate_ in order to raise an exception.

class RegistrationForm(Form):
  amount = IntegerField('amount', validators=[Required()])

  validate_unique_name(self, field):
    if field.data > 10000:
      raise ValidationError('too much money')

in my case I used it like so to validate that a user was not in the database already:

class Registration(Form):
  email = StringField('Email', validators=[Required(), Email()]) # field for email
  # ...
  def validate_email(self, field): # here is where the magic is
    if User.query.filter_by(email=field.data).first(): # check if in database
      raise ValidationError("you're already registered")
Share:
11,606
applechief
Author by

applechief

Updated on July 27, 2022

Comments

  • applechief
    applechief almost 2 years

    I have a registration form that collects credit card info. The workflow is as follows:

    • User enters registration data and card data through stripe.
    • The form is validated for registration data.
    • If the form is valid, payment is processed.
    • If payment goes through, it's all good, the user is registered and moves on.
    • If the payment fails, i want to be able to raise a validation error on a hidden field of the form. Is that possible?

    Here's a the form submission code:

    def register():
    form = RegistrationForm()
    if form.validate_on_submit():
    
        user = User(
            [...]
        )
    
        db.session.add(user)
    
        #Charge
        amount = 10000
    
        customer = stripe.Customer.create(
            email=job.company_email,
            card=request.form['stripeToken']
        )
        try:
    
            charge = stripe.Charge.create(
                customer=customer.id,
                amount=amount,
                currency='usd',
                description='Registration payment'
            )
        except StripeError as e:
            ***I want to raise a form validation error here if possible.***
    
        db.session.commit()
        return redirect(url_for('home'))
    
    return render_template('register.html', form=form)
    
  • Nicolas L
    Nicolas L almost 10 years
    Isn't this approach prone to a race condition?
  • Patrick Yan
    Patrick Yan over 9 years
    The solution is working for me for StripeError, but I'm also geocoding with Google and then trying to raise an error using the form.field.errors.append('') method, but the error won't show up.
  • Patrick Yan
    Patrick Yan over 9 years
    The problem was that adding errors doesn't stop the rest of the code from executing (I had a redirect at the end). I added additional code to check if the form still had errors before redirecting.
  • Sam
    Sam about 5 years
    If you get "AttributeError: 'tuple' object has no attribute 'append'", see stackoverflow.com/a/22889381/328817