Colander node for multiselect

81 views
Skip to first unread message

Mike Orr

unread,
Oct 17, 2014, 6:36:01 PM10/17/14
to pylons-...@googlegroups.com
What's the right Colander node for a multiselect form field? I'm using
Colander with 'smallform' in a Pyramid application. I want a list of
strings, possibly empty, from a constrained set of choices.

SchemaNode(List(), validator=ContainsOnly([...]))

says a correct string value is invalid because it's "not iterable".

I'm now trying a SequenceSchema class with a string SchemaNode:

class PostTag(SequenceSchema):
tag = SchemaNode(String), validator=OneOf([...])

But how do I indicate that it's optional, and that I want the missing
value to be an empty list rather than None? Also, while it's nice that
I can validate the type of each element this way, it's overkill for
strings, and I can't use the nice ContainsOnly that sounds like it's
what I want.

--
Mike Orr <slugg...@gmail.com>

Mike Orr

unread,
Oct 17, 2014, 7:43:53 PM10/17/14
to pylons-...@googlegroups.com
On Fri, Oct 17, 2014 at 3:35 PM, Mike Orr <slugg...@gmail.com> wrote:
> What's the right Colander node for a multiselect form field? I'm using
> Colander with 'smallform' in a Pyramid application. I want a list of
> strings, possibly empty, from a constrained set of choices.

It turned out to be two different problems, only one related to Colander.

``request.POST`` is a WebOb MultiDict but Colander and 'smallform'
treat it like a regular dict, so they only saw the last value and
presumed it was single. I switched to ``request.POST.mixed()``, which
produces a regular dict with lists for multiple values.

On the Colander side, I still haven't gotten Sequence, List,
SequenceSchema, or Set to work with all three cases of multiple
values, single value, or zero values.

I tried to think of how it works in FormEncode, but it may be that I
never had multiselects in my FormEncode forms.

Back to WebOb. I don't like things that change type depending on
whether the value is single or multiple, so I may prefer
``request.POST.dict_of_lists()``, which makes all values lists. But
that would cause even more problems interfacing with Colander scalar
types.

> SchemaNode(List(), validator=ContainsOnly([...]))
>
> says a correct string value is invalid because it's "not iterable".
>
> I'm now trying a SequenceSchema class with a string SchemaNode:
>
> class PostTag(SequenceSchema):
> tag = SchemaNode(String), validator=OneOf([...])
>
> But how do I indicate that it's optional, and that I want the missing
> value to be an empty list rather than None? Also, while it's nice that
> I can validate the type of each element this way, it's overkill for
> strings, and I can't use the nice ContainsOnly that sounds like it's
> what I want.
>
> --
> Mike Orr <slugg...@gmail.com>



--
Mike Orr <slugg...@gmail.com>
Reply all
Reply to author
Forward
0 new messages