Section 3.4. Understanding CherryPy and TurboGears Controllers


3.4. Understanding CherryPy and TurboGears Controllers

At the center of a TurboGears application is CherryPy, responding to every user action and sending changes to the model and view.

In other words, CherryPy provides the controller part of the MVC paradigm in TurboGears, and that means that it is responsible for parsing user actions and passing state-change requests to your model objects. It also calls the view template and can pass it whatever data it needs to present to the user.

It sounds like a lot, but actually TurboGears makes writing controllers easy.

Although views can pull data from the model, many people prefer to gather up whatever the view needs and pass it into the view as a dictionary.

There are legitimate reasons to move this kind of logic from the view into the controller. For one thing, the less code you have in your view, the easier it is to get a designer to work with you on those pages. Also, you may need to package the same data for several different output formats (HTML, XML-RPC, JSON, and so on), and it helps to keep the data access logic centralized in a single controller.

By default, TurboGears creates a file controllers.py for your controller classes in the application sub-directory whenever you use tg-admin quickstart to create a new project.

Because a web-based application encapsulates every single user action into an HTTP Get or HTTP Post request, our controller layer needs to listen for those requests, interpret them, and call the appropriate method, passing in the appropriate parameters.

The good news is that CherryPy and the TurboGears framework take care of most of this work for you.

For example, CherryPy takes every incoming request, tries to match it up to the object hierarchy in your controller classes, and calls the appropriate method. Oh, and for good measure, it passes in any parameters that were embedded in the HTTP request.

We saw this in Chapter 2, "Getting Started with TurboGears," when we created the "hello" method. We requested http://localhost:8080/hello, and the hello method was called. If you created the goodbye method, the same thing happened there.

Let's take a look at some sample code that bypasses Kid templates and sends output directly to the browser:

class Root(controllers.RootController):     @expose()     def index(self, name="John Carter"):         return "I am %s, of Virginia" % name


Okay, so there's one more thing you have to understand to effectively use controllers in TurboGears, and that's the @expose() decorator. If you are new to Python, or just haven't used decorators before, this is easy.

TurboGears provides several decorators for controller methods. We talk about Turbo-Gears Decorators in depth in Chapter 17, "CherryPy and TurboGears Decorators," but we can get going with just @expose.

@expose provides a quick and easy method for you to use to say whether that particular method is public or private. You can also provide a view template that can be used to display the data your controller returns.

The syntax is simple, enabling you to expose a controller method to the web with one line:

@expose() def index(self):     pass


And if you want to send that to the index.kid template, you can do it by adding the name and location (in standard Python dotted notation) to the .expose decorator like this:

What Is a Decorator?

A decorator is a way to tell Python to do some extra stuff automatically whenever a function is called. This means you can use a decorator to easily add similar functionality to a whole bunch of methodswithout repeating code. This is particularly useful for "cross-cutting" concerns such as security that would otherwise end up "infecting" all of your classes with a bunch of similar code.

In Python, functions are "first-class objects," which means you can pass a function around just like any other object. So, if we wanted to log any access to a function, we could write a logging_decorator() that takes care of the logging.

Before the advent of decorators in Python 2.4, we could write code like this to ensure that our logging_decorator() is always called before the fun() function:

def fun(x):     ... fun = logging_decorator(fun)


The last line replaces the original fun() object with a brand new function object created by calling the logging_decorator function, and passing in our original fun object as a parameter. The new fun object we've created will run the logging decorator, and when that's done it will run the original fun() function, which then gets to do its thing, without any knowledge of the logging that just happened.

Python 2.4 decorator syntax makes this process even easier:

@logging_decorator def fun(x):     ...


The @logging_decorator is semantically equivalant to fun = logging_decorator(fun). It wraps fun() with a call to logging_decorator, without the need to repeat the name of the original function three times.

TurboGears and CherryPy provide several decorators in addition to @expose() that you can use in your controllers to make your life easier. We explore those decorators in depth in Chapter 17.


@expose(template="project_name.templates.index") def index():     pass


Where project_name is the name of your project!




Rapid Web Applications with TurboGears(c) Using Python to Create Ajax-Powered Sites
Rapid Web Applications with TurboGears: Using Python to Create Ajax-Powered Sites
ISBN: 0132433885
EAN: 2147483647
Year: 2006
Pages: 202

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net