How can I disable the wtforms SelectField choices validation?
Asked Answered
H

3

12

I have a wtforms form

class MyForm(Form):
    names = SelectField('name', choices=[])

The choices of names field is built dynamically and rendered in the template by an ajax call. When I submit the form, it raises an exception "not a valid choice". I don't want the form to validate the choices of names field for me. How can I disable the validation?

Heartsome answered 21/1, 2013 at 6:0 Comment(1)
Why do you add a choices parameter, then? Why not names = SelectField('name')?Krystin
W
13

I did something like this to step around the SelectMultipleField validation in WTForms. It should work the same way with a plain SelectField

class NonValidatingSelectMultipleField(SelectMultipleField):
    """
    Attempt to make an open ended select multiple field that can accept dynamic
    choices added by the browser.
    """
    def pre_validate(self, form):
        pass

I simply override the built-in validation.

Waterfowl answered 8/7, 2015 at 2:24 Comment(2)
This is exactly right. In case anyone is interested, here's the pre_validate code you're skipping:Reconnoitre
That was for the normal SelectField. Here is for SelectMultipleFIeld: def pre_validate(self, form): if self.data: values = list(c[0] for c in self.choices) for d in self.data: if d not in values: raise ValueError(self.gettext("'%(value)s' is not a valid choice for this field") % dict(value=d))Reconnoitre
S
8

I was stuck with the same issue. The solution provided by Xealot is great. I found that there is an option to set validation to False using validate_choice=False. I have included an example of both the solutions below.

class NonValidatingSelectField(SelectField):
    """
    Attempt to make an open ended select multiple field that can accept dynamic
    choices added by the browser.
    """
    def pre_validate(self, form):
        pass

class MyForm(Form):
    names = NonValidatingSelectField('name')
    names2 = SelectField('name2', validate_choice=False)
Shallot answered 12/4, 2021 at 19:28 Comment(2)
For anyone stumbling on this thread and facing the same problem, setting validate_choice=False is the right solution to adopt for version 2.x+Mas
I had version 2.2.1 and validate_choice was not yet implemented. Sharing in case it saves someone else the headachePavlov
C
0

By "I don't want the form to validate the choices", I assume you actually mean "I'm going to do it myself later and doubt the form's ability to do it correctly".

But you are in luck! You can subclass an existing form to add choices dynamically.

class MyForm(Form):
    # other fields...


def some_handler(request):
    name_choices = build_name_choices()
    class RealForm(MyForm):
        names = SelectField('name', choices=name_choices)

    form = RealForm(request.GET)
    form.validate()

This also saves you from the tedium of merging the form's validation and error messages with those you generate yourself later.

Caliginous answered 21/1, 2013 at 6:10 Comment(1)
You just replaced the author's question with your own and answered it. I have this need also and it is still the wrong assumption. My need is to have open choices that are added dynamically on the client, thus unknown on the server.Waterfowl

© 2022 - 2024 — McMap. All rights reserved.