On Mon, Apr 5, 2010 at 12:54 PM, Tim Black <[email protected]> wrote:
> Mike Orr wrote:
>
> On Mon, Apr 5, 2010 at 6:36 AM, Tim Black <[email protected]> wrote:
>
>
> I'm beginning to think that when I write controllers named things like
> getTaskHTML() or setTaskHTML() when I have a model.Task object but it
> doesn't have an attribute named HTML, I should refactor those methods to
> this form:  model.Task.HTML where HTML is a Python property or is accessible
> via __setattr__ and __getattribute__.  In general, if I'm writing controller
> methods that are merely basic manipulations of model objects, I'm thinking I
> should put those methods into the model rather than the controller.  Is that
> correct?
>
>
> Philosophically, the model shouldn't have any  structural (WSGI- or
> HTTP-specific) or UI (HTML-specific)  code in it.  The input values
> are coming from POST parameters, which the model shouldn't know about.
>  The model should make sense outside a web context.  So there should
> be at least a thin layer validating/translating the input to generic
> arguments.
>
>
> I agree.  I should have used a more appropriate example--the one I'm working
> on right now is that I have a model class named Task which contains tasks
> arranged in a tree structure represented by means of a column named "parent"
> which contains the parent task's id.  I'm displaying the total of the
> estimated and actual hours for that task by adding up those columns for all
> of each task's children.  So, instead of my current controller methods named
> getTaskEstimatedHours() and setTaskEstimatedHours(), because the values
> those methods return can naturally be conceived of as attributes of a model
> object instance, I think I should put those methods under an accessor named
> model.Task.estimated_hours.  At first I left such methods out of the model,
> but now I'm thinking it's better to put them in the model to make the
> controllers less cluttered.  Is that a wise direction to go?

If it's high-level logic based on model data (not on parameters or
HTML strings), the model is a good place for it.  You can use ORM
class methods to return a query or result based on multiple records,
or separate functions.  So, your "get" function would add up the hours
in the various records, and the "set" function would distribute the
hours to the appropriate records.

There are two approaches to the model. The minimal approach is to put
only the table definitions in it (and everything else in the
controller).  The maximal approach is to push as much high-level
business logic as possible into the model. I prefer the maximal
approach.

So basically, the controller converts parameters to model structures,
and sets 'c' variables for the template. Pylons doesn't have a
separate view-logic level, so sometimes view logic is put into the
controller for convenience (rather than using a complex Python escape
in the template, which is harder to debug).

Shared controller code can be made into methods of the controller
class, put into the base controller, or into an immediate subclass. I
sometimes use such methods to copy a bunch of form result values to
'c' variables.

There are other ways to structure things if you write your own code.
For instance, you could define "view modules" -- functions the
controllers call, which in turn invoke the templates. That provides a
separate place for view logic.

You can also change the MVC model. "MVC" itself was defined for a
totally different context than web applications, and we see it's not a
perfect fit. There are several different interpretations of MVC, each
equally valid. Django calls the controller the "view", the view merely
the "template", and the framework the "controller". Some Java and
wxPython applications have a totally different way, in which the
controller passes a model object to the view, and the view manipulates
it directly to produce the result. (This goes further than just
passing an ORM object or query object to the template.) You can do
these in Pylons but you'd have to write your own code for it.

'helpers' is for little functions that are used across a wide
cross-section of templates and perhaps controllers. They tend to be
data-formatting functions, although they could also do lookups and
other things. In some ways they allow a bypass of the MVC structure
when it's worthwhile.

-- 
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