Search code examples
pythonflaskwtformsflask-wtforms

Validate that a WTForms BooleanField is checked


I am creating a form using Flask-WTForms.

I am using a BooleanField so that a user can indicate they agree terms.

I cannot validate the BooleanField upon submission to ensure that it has been checked. I have tried using Required(), DataRequired() and custom validation but in each case I have not received a validation error.

Here are the nuts and bolts of the application:

from flask import Flask, render_template, session, redirect, url_for, flash
from flask_wtf import Form
from wtforms import BooleanField, SubmitField
from wtforms.validators import Required, DataRequired
from flask_bootstrap import Bootstrap

app = Flask(__name__)
app.config['SECRET_KEY'] = 'impossibletoknow'

bootstrap = Bootstrap(app)

class AgreeForm(Form):
    agreement = BooleanField('I agree.', validators=[DataRequired()])
    submit = SubmitField('Submit')


@app.route('/', methods=['GET', 'POST'])
def index():
    form = AgreeForm()
    if form.validate_on_submit():
        agreement = form.agreement.data
        if agreement is True:
            flash('You agreed!')
        return redirect(url_for('index', form=form))
    form.agreement.data = None
    agreement = False
    return render_template('index.html', form=form)


if __name__ == '__main__':
    app.run(debug=True)

And here is the index.html template...

{% import "bootstrap/wtf.html" as wtf %}

{% block content %}
<div class="container">
    {% for message in get_flashed_messages() %}
    <div class="alert alert-warning">
        <button type="button" class="close" data-dismiss="alert">&times;</button>
        {{ message }}
    </div>
    {% endfor %}
    {{ wtf.quick_form(form) }}
</div>
{% endblock %}

Any suggestions would be gratefully received.


Solution

  • Works for me— you do need to use DataRequired() (Required is being deprecated):

    from flask import Flask, render_template
    from flask_wtf import Form
    from wtforms import BooleanField
    from wtforms.validators import DataRequired
    
    app = Flask(__name__)
    app.secret_key = 'STACKOVERFLOW'
    
    class ExampleForm(Form):
        checkbox = BooleanField('Agree?', validators=[DataRequired(), ])
    
    @app.route('/', methods=['post', 'get'])
    def home():
        form = ExampleForm()
        if form.validate_on_submit():
            return str(form.checkbox.data)
        else:
            return render_template('example.html', form=form)
    
    
    if __name__ == '__main__':
        app.run(debug=True, port=5060)
    

    Template:

    <form method="post">
        {{ form.hidden_tag() }}
        {{ form.checkbox() }}
        <button type="submit">Go!</button>
    </form>
    
    <h1>Form Errors</h1>
    {{ form.errors }}