Django and usermanager custom user model

I am building a web application with Django 1.5. I am using a user user model with a custom UserManager. I followed the instructions and examples of the official Django documentation.

Now, when I try to create a new user using UserManager.create_user(...) , I get a NoneType error: it seems UserManager attribute models are of type None. I think I'm setting up the UserManager correctly in the User model ( objects = UserManager() )

I really don't know where I am making a mistake. My coding partners stand, and I'm new to Django. Maybe you can help us.

Here is the code:

 class UserManager(BaseUserManager): """ create a new user @param username: the name for the new user @param password: the password for the new user. if none is provided a random password is generated @param person: the corresponding person object for this user """ def create_user(self, username, person, password=None): if not username: raise ValueError('User must have a valid username') user = self.model(username=username, created=datetime.now(), must_change_password=True, deleted=False, person=person) user.set_password(password) user.save(using=self._db) return user class User(AbstractBaseUser): ## the id of the user. unique through the application user_id = models.AutoField(primary_key=True) ## the name of the user. unique through the application username = models.CharField(max_length=32, unique=True) ## the date when the user was created created = models.DateTimeField() ## iff this is true the user must set a new password at next login must_change_password = models.BooleanField(default=True) ## iff true the user is marked as deleted and can not login deleted = models.BooleanField(default=False) ## iff true the user is admin and has all permissions. use with care! is_admin = models.BooleanField(default=False) ## reference to the person entity that is linked to this specific user person = models.ForeignKey(Person) ## indicates if the user is active or not active = models.BooleanField(default=True) ## define the user manager class for User objects = UserManager() # necessary to use the django authentication framework: this field is used as username USERNAME_FIELD = 'username' 

I get a NoneType error in the line user = self.model(..) in the create_user () method in UserManager

+6
source share
4 answers

To create a new user, you should not 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 the docs here.

+6
source

I also had problems saving the user model and it took me a while to figure it out

I think the important line in your code is:

 objects = UserManager() 

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

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

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

+5
source

I had to add an answer because I do not have enough comments for comments. But the link in @ Aldarund's answer does not describe the use of get_user_model () at all. However, this link should help ...

+2
source

An important warning for updating solutions ... If you encounter such a problem, you probably tried various solutions on the Internet, suggesting you add AUTH_USER_MODEL = users.CustomUser to settings.py and then 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 an error:

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

At any time, your code refers to User such as:

 User.objects.get() 

Because you know that you have already placed objects = UserManager() in your user class ( UserManager is the name of your user manager extending BaseUserManager ).

Well, as it turns out (thanks @Aldarund):

 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 

NOT equivalent:

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

It may not be intuitive, but it turns out that in python, executing User = get_user_model() once during the import does not cause User be defined on subsequent calls (that is, it does not turn User into a kind of "constant"). what can you expect if you come from C / C ++ background, which means that the execution of User = get_user_model() occurs during import, but then User = get_user_model() before the next User = get_user_model() class or function / method in this file )

Thus, to summarize, in all files that reference the User class (for example, calling functions or variables like 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 time for others ...

0
source

Source: https://habr.com/ru/post/945253/


All Articles