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.
