What is the 'correct' way to extend the base
auth_user
table/the wholeauth
system in order to support a number of custom user profile fields (such as username, location, birthday, etc.)?
I've caught glances of approaches from Googling, but no one ever seems to give a straight answer. The answer seems to be either completely replacing the base auth_user
table with a custom one (and letting the auth system know), or creating a new extension table with a foreign key reference back to the base auth_user
table. The first seems to have reusability problems, the second is going to have problems with forms and such.
Does anyone have any pointers to patch in something as universal as custom user profiles without breaking too much?
EDIT: A bit more reading suggests overriding the base auth_user
table is the way to go, and after some trial and error, I've found it's as easy as dropping in a block of code:
# before define_tables()
auth.settings.table_user = db.define_table('auth_user',
Field('email', length=128,label=T('Email'), default='', unique=True),
Field('user_name', length=128, label=T('User name'), default='', unique=True,
requires=IS_NOT_IN_DB(db, 'auth_user.user_name')
),
Field('password', 'password', readable=False, label=T('Password'),
requires=CRYPT()
),
Field('first_name', length=128, label=T('First name'), default='',
requires=(IS_NOT_EMPTY(error_message=auth.messages.is_empty),
IS_NOT_IN_DB(db, 'auth_user.first_name'))
),
Field('last_name', length=128, label=T('Last name'), default='',
requires=(IS_NOT_EMPTY(error_message=auth.messages.is_empty),
IS_NOT_IN_DB(db, 'auth_user.last_name'))
),
Field('registration_key', length=128, default='', writable=False, readable=False),
Field('country', 'string', length=15, label=T('Country'),
requires=IS_NULL_OR(IS_IN_SET(('England')))
),
)
So long as this gets executed after auth = Auth(db)
and before auth.define_tables()
in models/db.py, it all seems to work out okay. The fields show up on the user profile page, and everything else still works as expected.
Not sure how to answer my own question, so in the meantime, if someone could explain why this is the right way to do it, and what else must be kept in mind, I'd appreciate it!
auth.settings.table_user_name
stores the name of the user table (which defaults to auth_user
), and auth.settings.table_user
is a reference to the user table itself. Those two settings are used elsewhere in the Auth code, so that's why it is important to update them when you create a custom user table (in your case, you don't need to update auth.settings.table_user_name
because you kept the default name). There is a section in the book demonstrating this method of customizing Auth tables.
Note, if you just want to add some extra fields to the default auth_user
table, instead of redefining the entire table as you have done, you can simply do:
auth.settings.extra_fields[auth.settings.table_user_name] = [Field('myfield1',...),
Field('myfield2',...), etc.]
before calling auth.define_tables()
, and those extra fields will be appended to the auth_user
table. Note, if there are some fields in the default auth_user
table that you simply don't want to use, you can hide them in registration and profile forms by setting their readable
and writable
attributes to False
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With