Done, new gist http://gist.github.com/302617, ticket updated.
@validate now uses the same _parse() and _render_invalid() methods
used by the example below.

    def update(self):
        try:
            self._parse(request, schema=MyForm())
            # Here self.form_result is populated as normal
            # as is self.params, the decoded but unconverted form
params or
            # json request.  You could do more stuff here that raises
            # formencode.Invalid, validated model updates for example.
        except Invalid as e:
            return self._render_invalid(e, form='edit')
        # Do more stuff with self.form_result, e.g.
        if accepts_json():
            return
render_json(json_serialisable_thing_made_from_form_result)
        else:
            return render('template')

Regards,
Mike

On Feb 12, 12:48 am, Mike Burrows <[email protected]> wrote:
> Oops - it's getting late here but I forgot the form parameter required
> by the error handler and this makes a nonsense of some of what
> followed (ok I got carried away):
>
> try:
>     data = self.parse(request)
>     # maybe do something with data here, like save to the model
> except formencode.Invalid as e:
>     return self.render_invalid(e, form='edit')
> # do more with data here
>
> Mike
>
> On Feb 11, 10:14 pm, Mike Burrows <[email protected]> wrote:
>
> > Yes that's a much better pattern.  You could even move the "except" to
> > the end and push some validation to the model.
>
> > One thing my version shows however is that it's very easy to cover
> > more than just the html case.  So direct references to htmlfill should
> > be avoided, and either request.params needs somehow to work for json
> > (and potentially other formats) or the validator gets sent the full
> > request object.  And it's going to get repetitive, so even if it's
> > using a new validator object under the covers I would be tempted to
> > make it look something like
>
> > try:
> >     data = self.parse(request)
> >     # maybe do something with data here, like save to the model
> > except formencode.Invalid as e:
> >     return self.render_invalid(e)
> > # do more with data here
>
> > Push the exception handling up to the dispatcher and you get
>
> > data = self.parse(request)
> > # do stuff with data
>
> > Rename "data" to something more meaningful ("form_data" say) and make
> > it a memoized property and you're left with
>
> > # do stuff with self.form_data
>
> > Fun though this is (and I will try tomorrow to implement at least some
> > of the above patterns before commenting on the ticket) I'd like to
> > express a strong hope that Pylons 1.1 will be more format-aware. Some
> > content negotiation will be needed; mine's incomplete but it's a
> > start, and I'd surprised if there weren't better solutions out there
> > already.  The {.format} enhancement for Routes isn't strictly required
> > but it does work and it does give tidier config, so I hope that it (or
> > something very much like it) gets adopted too.
>
> > Regards,
> > Mike
>
> > On Feb 11, 6:13 pm, Mike Orr <[email protected]> wrote:
>
> > > On Thu, Feb 11, 2010 at 9:54 AM, Mike Burrows <[email protected]> wrote:
>
> > > > Personally, I would be happy to see a decorator-free Pylons but I say
> > > > that without knowing what our action methods will look like without
> > > > them!
>
> > > You can do it now; the trouble is you either have to work up from a
> > > minimal try/except or work down from the @validate code. The problem
> > > with the @validate code is it's hard to separate the universal pattern
> > > from the specific argument slinging the decorator does.
>
> > > The pattern is something like this (untested):
>
> > > '''
> > > try:
> > >     val = MyValidator()
> > >     data = val.to_python(request.params, None)
> > > except formencode.Invalid, e:
> > >     html = self.form_method()
> > >     html = htmlfill.render(html, request.params,
> > >         e.unpack_errors(), force_defaults=False)
> > >     return html
> > > # Success, perform action using ``data``.
> > > '''
>
> > > The render args are the source HTML, input values, and errors.
> > > ``e.unpack_errors()`` converts the error dict from a nested structure
> > > (if applicable) to the flat HTML format. ``force_defaults=False``
> > > prevents htmlfill from unsetting radio buttons and selects.
>
> > > I would read the source code for render (formencode/htmlfill.py) and
> > > Invalid (formencode/api.py) to get a feel for what exactly it's doing
> > > and the possible arguments.
>
> > > --
> > > 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