> I don't really mock the cherrypy package for testing. I just toss in a
> fake request. Adding a self.request reference to the controller seems
> reasonable for convenience's sake. Can you open a ticket for that?
> (http://trac.turbogears.org)

Added: http://trac.turbogears.org/turbogears/ticket/257

> The problem with this is that all of your functions would either have
> to have **kw or specifically have a validation_errors parameter. Other
> ideas that have been discussed are to call another method (if
> available) to handle errors. (yourmethodname_error).

Only functions that are expecting form input -- and they have to define
widgets and/or put input_form or validators in the decorator, so they
are already specialized for form processing.

I'll lay out my whole thought process, though I know this is
recapitulating a lot of the debate -- so, apologies in advance...

I think the problem is really thorny, and I don't see a clear solution.
The otherwise-pretty-swell cherrypy feature of converting user input
into method params makes dealing with validation in a generic way
extremely difficult. First, you need to define validators in the
decorator, and run them before the function runs, so that data types
are converted properly. Then the decorator also has to know what form
you're using so the widgets can marshal their input and do their own
validation.  All of that necessarily occurs outside of your function
body -- it's awfully confusing, at least to me. Not to mention that you
basically have no choice but to build the form in another method of the
controller, as DataController does.

So it seems to me that cherrypy and the widgets are pulling in opposite
directions on the same rope. One side wants to carve user input up for
you into method params, but the other needs full access to it... In
practice, I suspect that basically every form processing method is
going to have the signature:

  def whatever(self,**input):
       ...

And at that point, I'd rather let the widgets do all of the work:

      form = make_form_somehow()
      form.input(input)
      if form.errors:
          ...
      else:
          do_something_with(form.input) # typed and validated

But that would mean that all forms that want to do validation (other
than hand-coded each time) would be tied to widgets, which I figure is
probably not acceptable.

So that leaves either having to poll for errors (through
cherrypy.request or self.request or however), or being told about them.
For my money, it's better to be told. That's why I like adding a param
to the function call in the error case.

> Agreed, to a point. It's always been my intention to pull the bulk of
> the code out of that [TableForm]... but, in the end, it's a widget that
> renders out a form that is laid out table-style.

What I had in mind was pulling the guts out into a Container class, and
making TableForm a mostly-empty subclass of that.

> Tickets are cool. patches even better!

Look for some next week.

> Thanks! (And thanks for nose! it keeps getting better and nicer to use...)

Cool! Glad to hear it.

JP

Reply via email to