Skip to content

Instantly share code, notes, and snippets.

What would you like to do?
Checkbox WTForms Example (in Flask)
<!DOCTYPE html>
<html lang="en">
<meta charset="UTF-8">
<form method="post">
{{ form.hidden_tag() }}
{{ form.example }}
<button type="submit">Submit</button>
from flask import Flask, render_template
from flask_wtf import FlaskForm
from wtforms import widgets, SelectMultipleField
SECRET_KEY = 'development'
app = Flask(__name__)
class MultiCheckboxField(SelectMultipleField):
widget = widgets.ListWidget(prefix_label=False)
option_widget = widgets.CheckboxInput()
class SimpleForm(FlaskForm):
string_of_files = ['one\r\ntwo\r\nthree\r\n']
list_of_files = string_of_files[0].split()
# create a list of value/description tuples
files = [(x, x) for x in list_of_files]
example = MultiCheckboxField('Label', choices=files)
def hello_world():
form = SimpleForm()
if form.validate_on_submit():
return render_template("success.html",
print("Validation Failed")
return render_template('example.html',form=form)
if __name__ == '__main__':
<!DOCTYPE html>
<html lang="en">
<meta charset="UTF-8">
{{ data }}
Copy link

ondoheer commented Jul 6, 2014

Thanks, this was precisely what I was looking for

Copy link

AlexFrazer commented Aug 15, 2014

awesome, this helped

Copy link

jetpackdata commented Nov 5, 2014

Thanks for the snippet - was super helpful. Not sure if they modified the flask-wtf extension, but I couldnt import widgets from instead i did it from wtforms directly to get it to work

from wtforms import widgets

Copy link

edouardberthe commented Jun 9, 2015

Thank you, it's exactly what I'm looking for ! :)

However "from import widgets" didn't work for me, because there was neither "ListWidget" nor "CheckboxInput" in it.
I had to do "from wtforms import widgets"

Copy link

clime commented Feb 26, 2016

Thank you, very useful.

Copy link

victor-torres commented Mar 11, 2016


Copy link

robinclark007 commented Apr 13, 2016

thanks , your helped me

Copy link

plpxsk commented May 26, 2016

can anyone post link to what this looks like?

Copy link

jonathan-kosgei commented Sep 7, 2016

How to set the first field in the select box to be disabled and something like 'Choose your option' ?

Copy link

chewarer commented Oct 14, 2016

Thanks for the example.
It's my code:

choices = [(1, 'one'),
           (2, 'two'),
           (3, 'tree')]
resident = MultiCheckboxField('Label',
                              choices=choices, coerce=int)

In my form this checkboxes displayed as intended. But on page with form results, I can render only key of choice(number). How to render a text value of choice?
In Jinja template:

{% if form.resident %}
    {{ }}
{% endif %}

Copy link

YohanObadia commented Jul 30, 2017

Would have been great to see how your example.html is made.

Copy link

gianlucascoccia commented Nov 9, 2017

Very helpful, thank you!

Copy link

pickboy900 commented Jan 25, 2018

You don't know how valuable it is for me.


Copy link

insomniac807 commented Mar 22, 2018

Yeah I would like to see how it is rendered in the html template. For me the border only surrounds the first option which makes it look very messy. a shame because the rest works beautifully

Copy link

Skillz-Interface commented Apr 10, 2018

Thank you

Copy link

samuelvarghese commented Aug 3, 2018

Any idea on how the example.html should be structured ? I'm not able to figure it out.

Copy link

MarcosMoss commented Aug 27, 2018

what does your look like?

Copy link

adamtongji commented Feb 25, 2019

Thanks a lot!

Copy link

1oh1 commented Apr 19, 2019


    <form method="post">
      {{ form.csrf_token }}
      {{ form.example }}
      <input type="submit">

Copy link

shyenatech commented Mar 8, 2020

The form.validate_on_submit() does not work in this case. It considers the values as invalid. Hence use form.is_submitted() to make it work.

if form.is_submitted():
print form.errors
return render_template('example.html',form=form)

Copy link

doobeh commented Mar 9, 2020

@shyenatech-- the code seems (admittedly outdated) but fine, are you sure you're including the csrf token {{ form.hidden_tag() }} to handle the security component? I've updated it for the new version of Flask-WTF here: to give you an idea of how you don't have to skip the important validation step. Good luck!

Copy link

MuhammedTech commented Jul 7, 2020

How to query data from db instead of choices=files

Copy link

sgarbidonna commented Nov 13, 2020

Hi! How I mark as checked a checkbox? Is for an edit form. Where I need to mark was already marked before on the create

Copy link

xelandar commented Sep 12, 2021

Thanks for this code example.

I was struggling with validating the form though. I needed at least one checkbox to be checked. Above comments mentioning form.validate_on_submit() or form.is_submitted() unfortunately didn't help.

After some googling I stumbled on this stackoverflow answer that finally helped.

My final custom validator code:

def validate(self, extra_validators=None):
  if super().validate(extra_validators):
    if not request.form.getlist('example'):
      self.example.errors.append('At least one checkbox must be selected')
      return False
      return True
    return False

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment