Django custom user model and usermanager

无人久伴 提交于 2019-12-04 06:55:04

To create new user you shouldn't call UserManager.create_user(...). Instead you should use :

from django.contrib.auth import get_user_model
get_user_model().objects.create_user(...)

This is how django managers work. You can read docs here

colins44

I also had problems saving the custom user model and it took me while to figure it our

I think the important line in your code is:

objects     =   UserManager()

within the User class, so in order to save the new user you need to call

new_user=User.objects.create_user(args, args, args, etc)

the "objects" is the item that calls the UserManager class and is called a manager in django

I had to add an answer as I don't have enough rep to comment. But the link in @Aldarund's answer does not describe the use of get_user_model() at all. However, this link should help...

Important caveat to update the solutions... If you're facing this kind of problem, you've probably tried various solutions around the web telling you to add AUTH_USER_MODEL = users.CustomUser to settings.py and then to add the following code to views.py forms.py and any other file that calls User:

from django.contrib.auth import get_user_model
User = get_user_model()

And then you scratch your head when you get the error:

Manager isn't available; 'auth.User' has been swapped for 'users.User'

Anytime your code references User such as:

User.objects.get()

Cause you know you already put objects = UserManager() in your custom user class (UserManager being the name of your custom manager that extends BaseUserManager).

Well as it turns out (thank you to @Aldarund) doing:

User = get_user_model() # somewhere at the top of your .py file
# followed by
User.objects.get() # in a function/method of that same file

Is NOT equivalent to:

get_user_model().objects.get() # without the need for User = get_user_model() anywhere

Perhaps not intuitive, but it turns out that that in python, executing User = get_user_model() once at the time of import does not then result in User being defined across subsequent calls (i.e. it does not turn User into a "constant" of sorts which you might expect if you're coming from a C/C++ background; meaning that the execution of User = get_user_model() occurs at the time of imports, but is then de-referenced before subsequent called to class or function/method in that file).

So to sum up, in all files that reference the User class (e.g. calling functions or variables such as User.objects.get() User.objects.all() User.DoesNotExist etc...):

# Add the following import line
from django.contrib.auth import get_user_model

# Replace all references to User with get_user_model() such as...
user = get_user_model().objects.get(pk=uid)
# instead of  user = User.objects.get(pk=uid)
# or
queryset = get_user_model().objects.all()
# instead of queryset = User.objects.all()
# etc...

Hope this helps save others some time...

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!