Flask - wtforms: check always false

First off, I'm new to python and Flask, so I'm sorry if my question is dumb. I am looking for it but have not found an answer (which should be "easy", I think).

I wanted to add a contact page on my website, I found this tutorial , so I followed it. Everything worked fine until the form was confirmed. I use only Required , and form.validate () always returns false. If I don’t touch my code, and I delete every Required in the form class, it works fine, form.validate () returns true.

I really don’t understand why, I read a lot that you need to use validate_on_submit () , but I get an error if I use it: * The ClassName object does not have the attribute 'validate_on_submit' *

Here are the relevant parts of the code:

Index.py

@app.route('/contact', methods=['GET','POST']) def contact(): form = ContactForm() if request.method == 'POST': if form.validate() == False: flash('All Fields are required.') return render_template('contact.html', form=form) else: return 'Form posted' elif request.method == 'GET': return render_template('contact.html', form=form) 

forms.py

 from wtforms import Form, TextField, TextAreaField, SubmitField, validators,ValidationError class ContactForm(Form): name = TextField("Name", [validators.Required()]) email = TextField("Email") subject = TextField("Subject") message = TextAreaField("Message") submit = SubmitField("Send") 

contact.html

 <div id="contact"> {% for message in get_flashed_messages() %} <div class="flash">{{ message }}</div> {% endfor %} <form action="{{ url_for('contact') }}" method=post> {{ form.name.label }} {{ form.name }} {{ form.email.label }} {{ form.email }} {{ form.subject.label }} {{ form.subject }} {{ form.message.label }} {{ form.message }} {{ form.submit }} </form> </div> 

I never got the line β€œForm Submitted” even when I write something in the β€œName” field.

Thanks in advance,

+6
source share
4 answers

You must initialize the form instance with the values ​​from the request:

 from flask import request @app.route('/contact', methods=['GET','POST']) def contact(): form = ContactForm(request.form) if request.method == "POST" and form.validate(): # do something with form # and probably return a redirect return render_template("contact.html", form=form) 

Here is a better tutorial than the one you ask in your question: http://flask.pocoo.org/docs/patterns/wtforms/ .

Look at the template rendering code in the tutorial, make sure that you visualize form field errors. If the form is submitted but does not validate the code, it will go to render_template with an instance of the form containing field validation errors (again, see the WTForms documentation and documentation).

+5
source

I always fail in form.validate_on_submit () when I test the login form after the demo code in Miguel Greenberg's book "Flask Web Development". Therefore, I think I should find a way to debug it.

The debugging approach that I take is to add the code below to app / auth / views.py:

 flash(form.errors) 

He then shows me the culprit when I run into the login page:

 errors={'csrf_token': ['CSRF token missing']} 

Therefore, I recommend using the form.errors message for debugging.

+9
source

Just ran into a problem, and the solution was to add hidden_tag right below the form in the template:

 ... <form action="{{ url_for('contact') }}" method=post> {{ form.hidden_tag() }} ... 
+2
source

Like @Paul Vergeev, just add:

 <form action="{{ url_for('contact') }}" method=post> {{ form.csrf_token }} 

This is necessary because your form includes validators, so it adds an "enter" type of "Hidden" to your html form. Without this hidden token in your html, the validator cannot check the input of your users, and the result of the check will always be False.

 {{ form.hidden_tag() }} 

will include all hidden input fields in your html code; but they will not appear on the page.

 {{ form.csrf_token }} 

will include only the hidden csrf_token input field in your html code; but they will not appear on the page.

One more thing: you have to configure the SECRET_KEY application. Do this by including app.config["SECRET_KEY"] = "a secret key you won't forget" just below the initialization of the application, that is, immediately after app = Flask(__name__) .

All this allows WTForms validators to protect your site from CSRF (often pronounced c-surf). You can also learn more about CSRF here .

+1
source

All Articles