Let's suppose you have a User
that is, optionally, a member of a Company. In
SQLObject you model it somehow like this:
class Company(SQLObject):
name = UnicodeCol(length=16, alternateID=True, alternateMethodName="by_name")
display_name = UnicodeCol(length=255)
class User(InheritableSQLObject):
company = ForeignKey("Company", notNull=False, cascade='null')
Then you want to implement a user settings interface that uses a Select box to choose the company of the user.
For the Select widget to properly handle the validator for your data, you need to put a number in the first option. As my first option, I want to have the "None" entry, so I decided to use -1 to mean "None".
Now, to make it all blend nicely, I overrode the company
setter to accept -1
and silently convert it to a None
:
class User(InheritableSQLObject):
company = ForeignKey("Company", notNull=False, cascade='null')
def _set_company(self, id):
"Set the company id, using None if -1 is given"
if id == -1: id = None
self._SO_set_company(id)
In the controller, after parsing and validating all the various keyword arguments, I do something like this:
user.set(**kw)
Now, the overridden method didn't get called.
After some investigation, and with the help of NandoFlorestan on IRC, we figured out the following things:
-
That method needs to be rewritten as
_set_companyID
:def _set_companyID(self, id): "Set the company id, using None if -1 is given" if id == -1: id = None self._SO_set_companyID(id)
-
Methods overridden in that way are alsop called by
user.set(**kw)
, but not by theUser(**kw)
constructor, so using, for example, a similar override to transparently encrypt passwords would give you plaintext passwords for new users and encrypted passwords after they changed it.