I wanted to provide some useful additional info to anyone else who may
have been reading....

One related issue that came up with inlining the validation and
performing schema validation manually is that for multiple selections
such as multiple selectfields, the ForEach validator only returns the
last selected value if you *dont* transform the request parameters
further with the multidict method mixed(). The reason it fails is that
there are multiple name value pairs corresponding to the multiple
selection fields and only the last pair is used.

In order words if you have any multiple selection fields (or checkbox
groups) that should return  a list of current selections- the
following piece of code wont work (only  the last value will be
returned) :-

try:
  c.form_result = schema.to_python(dict(request.params))
except formencode.Invalid, error:
....

you need to transform request params by calling the method mixed()
before passing the request parameters to your schemas to_python
method. i.e.

try:
  c.form_result = schema.to_python(dict(request.params.mixed()))
except formencode.Invalid, error:
....

And here is what mixed does :-

>>> print request.params.mixed.__doc__

        Returns a dictionary where the values are either single
        values, or a list of values when a key/value appears more than
        once in this dictionary.  This is similar to the kind of
        dictionary often used to represent the variables in a web
        request.


I was only able to figure this out by reading the validate decorator
to see how it handles multiple selection fields like checkbox groups.

I am not sure that this is readily documented. If someone would kindly
confirm that this would be the right way to handle this scenario then
perhaps we can consider documenting this appropriately.

On Jun 26, 1:24 pm, Mike Orr <[email protected]> wrote:
> On Wed, Jun 24, 2009 at 9:08 AM, afrotypa<[email protected]> wrote:
>
> > Hi,
>
> > I had a question about how @validate works
>
> > Say you have /controller/edit
>
> > which returns a form in a rendered template whose action is /
> > controller/save
>
> > As well the save action has an @validate decorator associated with
> > edits submitted form i.e. :-
>
> > @restrict('POST')
> > @validate(schema=TestSchema(), form='edit', post_only=False,
> > on_get=True)
> > def save(self, id=None):
>
> > If TestSchema fails to validate when @validate kicks in, this results
> > in edit being called (this looks like a method call not an HTTP get)
> > to re-generate the form for htmlfill to render with errors. This is
> > all fine an dandy if the select fields for the re-generated form have
> > the same options as when the form was initially generated and thus
> > there is no need to change the forms select field options.
>
> > However if regenerating the form requires a different set of select
> > options (which are dependent on the current select fields values
> > submitted in the original request), then the 2nd call to 'edit' will
> > need access to the request parameters in order to intelligently
> > regenerate the form. It appears request.params does not contain the
> > request parameters in this case. I was only able to obtain the current
> > form values in this case by doing something like this :-
>
> > params=dict(request.environ.get('webob._parsed_post_vars')[0])
>
> > This however does not look elegant and that variable is not guaranteed
> > to remain a part of the api in future webob versions.
>
> > Does anyone have an idea about how to handle this issue?
>
> @validate gets its data from the request object (called
> self._py_object.request in pylons.decorators.validate(), in the
> dynamic function 'wrapper').  If 'edit' is called, it is indeed a
> method call within 'wrapper'.
>
> So I don't know why request.params would not still contain the data in
> 'edit'.  I have also not heard of anybody regenerating a form with
> different settings than the user submitted, so it's possible that's an
> untested area.  Also, 'wrapper' calls htmlfill after 'edit' is called,
> which may affect things.
>
> @validate is due for a rewrite because it's not flexible enough, and
> it's too difficult to use parts of it without buying into its whole
> process.  There's a ticket open for 
> ithttp://pylonshq.com/project/pylonshq/ticket/405
> you can add any features you'd like to see to the ticket.
>
> In the meantime, I'd also consider inlining the validation code rather
> than using @validate.  That way you have full control over it.
> Essentially you'd have to recreate the 'try: validate, except Invalid:
> return self.edit()' pattern.  You may also want to consider a separate
> method to regenerate a failed form, so that 'edit' isn't trying to do
> too many different things depending on the situation.
>
> --
> Mike Orr <[email protected]>
--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups 
"pylons-discuss" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to 
[email protected]
For more options, visit this group at 
http://groups.google.com/group/pylons-discuss?hl=en
-~----------~----~----~----~------~----~------~--~---

Reply via email to