I’m a picky programmer and I like to have things “just so”. I’m creating an app using Turbogears and it’s Identity framework, but I wanted to have people log on using their email address rather than an arbitrary username. I didn’t fancy messing around with the SOProvider myself, nor did I want to just stuff an email address into a field called username in my database (I did mention I was picky, right?).
The solution is simple, but I thought I’d share this anyway as the theory behind it is fairly powerful.
class User(SQLObject):
email_address = UnicodeCol( length=255, alternateID=True,
alternateMethodName="by_email_address" )
....
def _get_user_name(self):
return self.email_address
def _set_user_name(self, new):
self.email_address = new
@classmethod
def by_user_name(self, text):
return self.by_email_address(text)
Now, as I said, this is pretty simple at first glance but it tricks SOProvider (or anything else that accesses the user_name property) into thinking that the user_name is a real item in the database. In effect, we are giving email_address an “alias” of user_name.
You can also use this method to provide some form of action on data before it hits your database:
class Car(SQLObject):
manufacturer = ForeignKey("Manufacturer")
model = UnicodeCol(length=50)
wheels = IntCol()
def _set_manufacturer(self, name):
try:
mf = Manufacturer.byName(name)
except SQLObjectNotFound:
mf = Manufacturer(name=name)
self._SO_set_manufacturer_id = mf.id
class Manufacturer(SQLObject):
name = UnicodeCol(alternateID=True)
I wrote this code on the blog, so it’s not tested in any way, but you get the idea. You’ll be able to create manufacturers on the fly when creating or updating a Car if they’re not already available. Neat, huh?
Ken Whitesell | 02-Jun-06 at 3:06 am | Permalink
Personally, I think using an email address as any type of identifier is a big mistake. Email addresses aren’t permanent. Even my ISP’s domain name has changed twice since I started using them about 4 years ago. I’d be in a world of hurt if I had to remember every email address I’ve ever used.
Tim Lesher | 02-Jun-06 at 12:03 pm | Permalink
I find email addresses to be far superior to arbitrary user names, because they’re much more likely to be unique. For example, on various sites, I have to log in as timl, tlesher, timlesher, timlesher, or timothylesher, because that’s what was available when I registered.
And using an email address as a login identifier doesn’t mean that a user can’t change it. The real unique identifier is the primary key in the database, which can be a value that the user never sees. There’s nothing wrong with allowing the user to change the email address with which he logs in after the fact.
Splee | 02-Jun-06 at 1:21 pm | Permalink
While I understand where you’re coming from Ken, I totally agree with Tim. Having to remember if I entered name1, name_1 or name142 because the username that is ideal was not available just doesn’t sit well with me.
As Tim said, if you change your email address there’s no reason why you can’t update your details.
Max Ischenko | 27-Jul-06 at 8:51 pm | Permalink
I used similar trick myself with email identities.
As for creating and auto-inserting new objects on the fly, I’m a little wary of this technique and prefer more explicitness. It does work OK with “Value Objects” (reference data) though.