I believe I figured out a way to reduce a few redundant lines from my controller methods. I’m looking for opinions about whether this is a wise idea.
At the top of nearly every method in my controllers, I look up the current user and the hospital this user belongs to, sort of like this:
@expose('.templates.m1')
def m1(self):
u = identity.current.user
hospital = u.hospital
Anyhow, I realized I can offload this irritating work to a validator that uses a state factory. Now my method looks like this:
@expose('.templates.m1')
@validate(validators=LookupSchema(), state_factory=my_state_factory)
def m1(self, u=None, hospital=None):
So now all my methods get called with those values already set up. I have to make u and hospital keyword parameters, because otherwise TG will try to pull their values out of the URL.
Here’s how it works. First I make my_state_factory that builds an object that has those values:
def my_state_factory():
class StateBlob(object):
pass
sb = StateBlob()
sb.u = identity.current.user
sb.hospital = u.hospital
return sb
Now the LookupSchema extracts those values out of the state blob object and adds them to the dictionary of values:
from formencode.schema import Schema, SimpleFormValidator
@SimpleFormValidator
def f(value_dict, state, validator):
value_dict['u'] = state.u
value_dict['hospital'] = state.hospital
class LookupSchema(Schema):
allow_extra_fields = True # otherwise, it fusses about self ?!?!?
chained_validators = [f]
So the benefit of all this is that some repetitive code is now just defined in a single place. Also, I’m getting more comfortable with the internals of FormEncode and the TG validate decorator.
Pretty soon, my controllers will be some really skinny methods. All the calculations of new variables based on the original parameters will happen outside the controller. The controller will just handle picking the right template.