Flask-WTF dynamic select field gives "None" as a string
Asked Answered
L

2

9

I have an empty select field that has choices that I define during run time:

myfield = SelectField('myfield', validators=[Optional()])

I'm trying to have this work with a GET request which looks like this:

@app.route('/', methods=['GET'])
def myresponse():
    form = myform(csrf_enabled=False)
    form.myfield.choices = (('', ''), ('apples', 'apples'), ('pears', 'pears'))

Then when I try to validate on an empty form. (I go to myapp.com with no GET parameters)

    if not form.validate():
        return search_with_no_parameters()
    else:
        return search_with_parameters(form) #this gets run

When my search_with_parameters function tries to use the form variables, it checks to make sure that the form.myfield.data is not Falsey (not an empty string). If it is not Falsey, a search with that parameter is done. If it is Falsey, that parameter is ignored. However, on an empty form submission, form.myfield.data is "None" as a string. And a search with "None" is done. I could validate against the "None" string but I think this defeats the purpose of using this module in the first place. Is there any way to make this just return an empty string or the real None value?

Landholder answered 17/2, 2016 at 15:3 Comment(2)
Not that it helps, but it seems to be by design: github.com/wtforms/wtforms/blob/master/tests/fields.py#L290Monecious
My pull request which fixes this was just merged: github.com/wtforms/wtforms/pull/288Monecious
C
9

I have found that adding a default parameter of the empty string solves the problem.

It appears that this is necessary to support the empty string as a choice/option with a SelectField.

Example:

myfield = wtf.fields.SelectField(
    u"My Field",
    validators=[wtf.validators.Optional()],
    choices=[(('', ''), ('apples', 'apples'), ('pears', 'pears'))],
    default=''
)
Cephalo answered 6/7, 2016 at 12:29 Comment(2)
Having to do this is arguably a bug in WTForms, since returning "None" as a string is just very odd indeed.Cephalo
Not obvious solution, I also think it's a bugScorpio
L
7

Ok, I made a workaround for this. I added a coerce definition to the field and changed the empty value from '' to 0 like this:

myfield = SelectField('myfield', validators=[Optional()], coerce=int)
...
form.myfield.choices = ((0, ''), (1, 'apples'), (2, 'pears'))

Of course, this only works because my real data was using integers as the values. I'm not sure how this would work if my data was strings.

Landholder answered 17/2, 2016 at 15:18 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.