Web2py has a lot of documentation, but you’ll find things you want to do that simply aren’t covered (at least, not where I could find).
One of those is getting the current user’s information, such as email, first name, last name, etc. Using auth.user_id gets the user id, but auth.email doesn’t exist. A little digging shows that auth had a data member called user that contains the user record.
So auth.user.email gets the email address of the current user (assuming the user is logged in).
I needed this because I wanted to default a field in a model to the current user’s email:
Field("email","string",default=auth.user.email)
Why would I want to do this, when that information already exists in the auth table? Isn’t that against database design practices?
Yes, it is, but remember that I’m targeting Google App Engine, which doesn’t support joins between tables efficiently. So to avoid joins, I need to denormalize the database (e.g. duplicate some data where it’s needed).
In this particular model, I have the user_id of the currently logged in user, but in the view for working with the model, I want to display the user’s email. Rather than do a join to get that info, I duplicate the email address in the model. That way I’m doing a simple select, rather than trying a join.
This puts the responsibility of ensuring the email addresses stay the same…so if the user changes their email, I need to also make sure this extra model gets updated.
Edit: I’ve discovered the above way of getting the current user’s email crashes the app if the user is not logged in. The problem is that the model.py file is evaluated for every page load. So when it tries to evaluate auth.user.email, and user is None, there’s no email attribute for it.
So we need to protect that default assignment. I used this:
default="" if not auth.user else auth.user.email
This seems to work okay, although it makes the model definitions look pretty messy. I’m sure there’s a better way of getting the same effect, but it works, so I’m happy.