Quirks when overriding SQLObject setters
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
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:
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
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 the
User(**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.