user authentication with extended (AbstractUser) user model

826 views
Skip to first unread message

Evan Stone

unread,
Jun 17, 2013, 10:31:16 AM6/17/13
to django...@googlegroups.com
Per the docs for Django 1.5, I have attempted to broaden the range of data held in the default user model by making an extended user model with the AbstractUser class. I made the model (called "Client") and listed it in settings.py as the AUTH_USER_MODEL. Syncdb took it and it worked great. Specifically, syncdb made a new MySQL table with all the default user fields AND my own additional fields, followed by two related tables for user permissions. I was pretty excited about all this until I tried to authenticate a user. Apparently, the built-in authenticate method is still pointing at the built-in user model. How can I point that method to my new custom model instead?

Fyi, I created new users in the Client model through the djangoized python shell and used set_password to create the passwords. I checked the MySQL tables to verify that my new user records in my Client table looked just like a new user in the built-in user table (auth-user). They did. But they won't authenticate. To double-check, I then made a new user in the built-in user model and it authenticated just fine. 

I've read about coding custom authentication with a totally customized user model--it looks quite involved and that really shouldn't be necessary for what I'm doing, because my model isn't custom. I've simply extended the existing user model and wish to authenticate users based on that model. There has to be an easier way. Any advice?

Thanks!

Russell Keith-Magee

unread,
Jun 17, 2013, 7:50:23 PM6/17/13
to django...@googlegroups.com
Hi Evan,

It's difficult to say what's going on without seeing code. However, if AUTH_USER_MODEL is set as you describe, then the built-in User table shouldn't even be created, so it shouldn't be possible for the built-in auth_user table to be used for authentication purposes.

So - it sounds like there's something wonky in your basic project configuration. 

The simplest test I can think of is to run ./manage.py createsuperuser.  This command should ask you for all the REQUIRED_FIELDS on your model, and then store an object with superuser permissions in your custom User table. If this doesn't happen, then you know you have a low level configuration problem. createsuperuser doesn't get involved with any of the authentication code -- it's a very low level tool for dealing with the "User" model (whichever User that is), so it's a good test to see if your project is finding your custom User model.

Another test would be to open a ./manage.py shell and run:

$ from django.contrib.auth import get_user_model
$ print get_user_model()

If that doesn't point at your custom User model, you have a problem.

As for your question about custom coding authentication -- this should only be needed if your custom User model doesn't meet the basic requirements of Django's User. If you have a single unique field that is an identifier (e.g., a username, and email address, or some other identifier of some kind), then you should be able to use Django's built-in authentication.

Yours,
Russ Magee %-)

Evan Stone

unread,
Jun 18, 2013, 11:37:40 AM6/18/13
to django...@googlegroups.com
Russ, 

Thanks so much for getting back to me! I shouldn't have posted that without my code in front of me... (was posting from my phone, in bed) 

It turns out that I did NOT have AUTH_USER_MODEL set. I had AUTH_PROFILE_MODULE set.

I changed it to AUTH_USER_MODEL and followed the custom user model example in the docs. I was really reluctant to do so earlier because the docs make it sound like everything is pain moving forward with a custom user model. Is it?

Russell Keith-Magee

unread,
Jun 18, 2013, 7:34:16 PM6/18/13
to django...@googlegroups.com
On Tue, Jun 18, 2013 at 11:37 PM, Evan Stone <ev...@aquapony.com> wrote:
Russ, 

Thanks so much for getting back to me! I shouldn't have posted that without my code in front of me... (was posting from my phone, in bed) 

It turns out that I did NOT have AUTH_USER_MODEL set. I had AUTH_PROFILE_MODULE set.

Ah - that'll do it :-) 
 
I changed it to AUTH_USER_MODEL and followed the custom user model example in the docs. I was really reluctant to do so earlier because the docs make it sound like everything is pain moving forward with a custom user model. Is it?
 
There are some things you need to keep in mind, but they're generally complications because you can't rely on User having a 30 character username and option email address, and so on. The trivial solution will always to be the builtin User model, but as long as you're aware of the assumptions you're making about your user model, switching to a new User model shouldn't be too much pain at all. The changes required should be relatively obvious -- for example, you'll need a new form definition for any User-based forms, because Django can't know what fields are needed for *your* User model.

Can you elaborate what aspect of the docs made you feel like the process of using a custom User model would be a pain? We added the feature because we feel it will be useful (and in my experience so far, it is). We want people to be aware that there will be complications, but we don't want to unilaterally scare people off. 

Yours,
Russ Magee %-)

Evan Stone

unread,
Jun 19, 2013, 4:16:05 PM6/19/13
to django...@googlegroups.com
Sure thing. Here are the snippets that gave me pause:

"Think carefully before handling information not directly related to authentication in your custom User Model.

It may be better to store app-specific user information in a model that has a relation with the User model. That allows each app to specify its own user data requirements without risking conflicts with other apps...."

along with

"One limitation of custom User models is that installing a custom User model will break any proxy model extending User. ..."

and

"Another limitation of custom User models is that you can’t use django.contrib.auth.get_user_model() as the sender or target of "

Evan Stone

unread,
Jun 19, 2013, 4:16:25 PM6/19/13
to django...@googlegroups.com
Also, thank you again!

Russell Keith-Magee

unread,
Jun 19, 2013, 8:13:04 PM6/19/13
to django...@googlegroups.com
On Thu, Jun 20, 2013 at 4:16 AM, Evan Stone <ev...@aquapony.com> wrote:
Sure thing. Here are the snippets that gave me pause:

"Think carefully before handling information not directly related to authentication in your custom User Model.

It may be better to store app-specific user information in a model that has a relation with the User model. That allows each app to specify its own user data requirements without risking conflicts with other apps...."

along with

"One limitation of custom User models is that installing a custom User model will break any proxy model extending User. ..."

and

"Another limitation of custom User models is that you can’t use django.contrib.auth.get_user_model() as the sender or target of "


Thanks for giving those details. I've opened ticket #20629 [1] to track this problem -- hopefully we can get this documentation cleaned up so we don't scare others in the future.


By way of explanation:

Points 1 and 2 are asking you to consider an architectural question -- do you need a custom user model at all? If you actually *are* using a username-based login system, and you just want to track some extra information about the user, the right approach may *not* be to create a custom user model.

Points 3 and 4 are pointing out known limitations. Proxy models are a problem because they use subclassing, and they will be subclassing the wrong class; signals are a problem because at the point the signal is registered, there's no guarantee that the User model has been correctly defined. There's not much we can do about (3); (4) is something that should get cleaned up when we eventually land app refactor.

Yours,
Russ Magee %-)

Evan Stone

unread,
Jun 20, 2013, 11:15:57 AM6/20/13
to django...@googlegroups.com
Thanks for opening the ticket and thanks so much for the explanation as well! 


-evan
Reply all
Reply to author
Forward
0 new messages