I've always read that if you needed to centralize your logic, that you should use modules instead of trying to do it in a model or trying to wire up one controller to another. I used global settings as an example, as you might need access to these settings in every controller, and duplicating the code in every controller goes against the Python and we2py's DRY (don't repeat yourself) principal. So this is why modules were created.
Granted, the GlobalSettings object I demonstrated is a very basic object that doesn't require you to instantiate it because it's all static. However, if you want to use more sophisticated objects, then the static class method may not work well. So there's another way to do this that I've been playing with. I am replacing a legacy application that is sort of like an ERP. The application keeps track of when employees clock in and clock out. Then, at the end of the week they print out their time cards. So, I wrote a TimeClock class in the same 'core.py' file described above. The big difference here is that the TimeClock object will have several functions, and I don't want to have to pass db, cache, and everything else for every function call, so I wrote it like this: class TimeClock: def __init__(self, environment, db): self.env = Storage(environment) self.request = self.env.request self.response = self.env.response self.cache = self.env.cache self.db = db def is_employee_clocked_in(self, employee): db = self.db timeclock_entry = db((db.timeclock.employee==employee) & (db.timeclock.endtime==None)).select().first() if timeclock_entry is None: return False else: return True Now, in my 'z_import_modules.py', I would add this (assuming I already did a local_import on core.py): timeclock = core.TimeClock(globals(), db) Then in any controller, if I want to check if an employee is clocked in: employee = auth.user if timeclock.is_employee_clocked_in(employee): print '%s is clocked in' % (employee.first_name) else: print '%s is not clocked in' % (employee.first_name) So with modules, you can make static classes for simple objects, like global settings that just load and save settings, or you can make complex objects that you instantiate in either the 'z_import_modules.py' file, or if you don't plan on using the module in every controller, then you could just remove the line we added in 'z_import_modules.py' to instantiate the 'timeclock' object, and use that line in whatever controller action we want. Hope this helps. So far this method seems to work really well. Oh, and to help you avoid some frustration in developing your modules, when you call local_import, you may also want to add reload=True to it. Without this, you would have to restart the web2py server every time you made a change to the module. Once you put your app into production, you would want to remove reload=True, as you don't want web2py to reload the module for every page load on a production server. So for testing, use this line: core = local_import('core', reload=True) And when you go into production, just remove 'reload=True'.