1

I know there are questions in SO regarding this issue. But most questions relates to AbstractBaseUser. I did not find any question with AbstractUser.

PROBLEM:

I want to implement authentication for django project. So I thought of implementing custom user model by inheriting AbstractUser.

Here is my Model:

class User(AbstractUser):

   phonenumber = models.CharField(max_length=25,unique=True)
   username = models.CharField(max_length=25,default="")
   profile_path = models.URLField(max_length=1500)
   country = models.CharField(max_length=100,default="")
   what_do_you_do = models.CharField(max_length=500,default="")
   where_do_you_do = models.CharField(max_length=500,default="")
   time_stamp = models.DateTimeField(auto_now_add=True,blank=True)


   USERNAME_FIELD = 'phonenumber'

I have added AUTH_USER_MODEL = 'XXX.User' in settings.py . And I thought of creating a super user.

   python manage.py createsuperuser

But it is giving me following error:

Traceback (most recent call last):
File "manage.py", line 22, in <module>
execute_from_command_line(sys.argv)
File "/home/sandesh/server/local/lib/python2.7/site-packages/django/core/management/__init__.py", line 367, in execute_from_command_line
utility.execute()
File "/home/sandesh/server/local/lib/python2.7/site-packages/django/core/management/__init__.py", line 359, in execute
self.fetch_command(subcommand).run_from_argv(self.argv)
File "/home/sandesh/server/local/lib/python2.7/site-packages/django/core/management/base.py", line 294, in run_from_argv
self.execute(*args, **cmd_options)
File "/home/sandesh/server/local/lib/python2.7/site-packages/django/contrib/auth/management/commands/createsuperuser.py", line 63, in execute
return super(Command, self).execute(*args, **options)
File "/home/sandesh/server/local/lib/python2.7/site-packages/django/core/management/base.py", line 345, in execute
output = self.handle(*args, **options)
File "/home/sandesh/server/local/lib/python2.7/site-packages/django/contrib/auth/management/commands/createsuperuser.py", line 183, in handle
   self.UserModel._default_manager.db_manager(database).create_superuser(**user_data)
TypeError: create_superuser() takes exactly 4 arguments (3 given)
4
  • Just making sure - have you applied migrations? Commented Nov 3, 2016 at 8:19
  • Yeah. I did. I did not implement UserManager. Does this error has anything to do with that @ApoorvKansal Commented Nov 3, 2016 at 8:21
  • which version of Djagno are you using? if it's >=1.8 you need to pass PermissionsMixin to your User class Commented Nov 3, 2016 at 9:00
  • You should probably create your own user manager. Commented Nov 3, 2016 at 9:01

3 Answers 3

4
from django.db import models
from django.contrib.auth.models import AbstractBaseUser, BaseUserManager



class MyUserManager(BaseUserManager):
    def create_user(self, phonenumber, password=None):
        if not phonenumber:
            raise ValueError('Users must have an phonenumber')

        user = self.model(
            phonenumber=phonenumber,
        )

        user.save(using=self._db)
        return user

    def create_superuser(self, phonenumber, password=None):
        user = self.model(
            phonenumber=phonenumber
        )
        user.is_admin = True
        print(password)
        user.set_password(password)
        user.save(using=self._db)
        return user


class User(AbstractBaseUser):

   phonenumber = models.CharField(max_length=25,unique=True)
   user= models.CharField(max_length=25,default="")
   profile_path = models.URLField(max_length=1500)
   country = models.CharField(max_length=100,default="")
   what_do_you_do = models.CharField(max_length=500,default="")
   where_do_you_do = models.CharField(max_length=500,default="")
   time_stamp = models.DateTimeField(auto_now_add=True,blank=True)
   is_admin = models.BooleanField(default=False)
   def has_perm(self, perm, obj=None):
    return self.is_admin
   def has_module_perms(self, app_label):
    return self.is_admin

   objects = MyUserManager()
   USERNAME_FIELD = 'phonenumber'

   @property
   def is_staff(self):
    return self.is_admin

   def get_short_name():
    return self.phonenumber

According to Django docs:

You should also define a custom manager for your User model. If your User model defines username, email, is_staff, is_active, is_superuser, last_login, and date_joined fields the same as Django’s default User, you can just install Django’s UserManager; however, if your User model defines different fields, you will need to define a custom manager that extends BaseUserManager providing two additional methods:create_user() and create_superuser()

As such, I have provided you a custom manager. Keep your settings as per normal. Note: As shown in your model, you have no password field so I assumed you did not need one in this case.

Also extend from AbstractBaseUser, not AbstractUser.

Sign up to request clarification or add additional context in comments.

4 Comments

Thank you @Apoorv, I have created it successfully. I created super user. but could not log into admin. it says Please enter the correct phonenumber and password for a staff account. Note that both fields may be case-sensitive. Does it need to do anything with password field in MyUserManager?
Updated the code to support password input. Please see changes. I was able to successfully login into the admin hub.
That helps Thank you very much. And now I can apply oath2 authentication right?
If you have problems with OAuth 1.0/2.0, please consider asking another question. As for now, I would suggest using requests-oauthlib.readthedocs.io/en/latest
3

The problem is in user model created by you.

    class User(AbstractUser):

       phonenumber = models.CharField(max_length=25,unique=True)
       username = models.CharField(max_length=25,default="")
       profile_path = models.URLField(max_length=1500)
       country = models.CharField(max_length=100,default="")
       what_do_you_do = models.CharField(max_length=500,default="")
       where_do_you_do = models.CharField(max_length=500,default="")
       time_stamp = models.DateTimeField(auto_now_add=True,blank=True)


       REQUIRED_FIELDS = ['username']

Add REQUIRED_FIELDS in your model.

One More thing,AbstractUser should be used if you like Django’s User model fields the way they are, but need extra fields.So it means,If you want to use AbstractUser,then you should add new fields in the user Model and not rewrite the predefined fields of Django auth user model. So you need to remove all the fields already inside Django User model or Use AbstractBaseUser for entirely new User Model.

Read further from Here.

2 Comments

I have added REQUIRED_FIELDS = ['username'] but it still gives me the same error.
@Naroju Read the whole answer. You need to remove USERNAME_FIELD = 'phonenumber' or if you want to customize the User model according to phonenumber,You should use AbstractBaseUser and not AbstractUser. AbstractUser itself is an extension of Django User Model.You can not override the fields already in it.You can just add more fields in AbstractUser.
-2

You can implementing custom usermodel like this way-:

from django.contrib.auth.models import AbstractBaseUser, UserManager
from django.contrib.auth.models import PermissionsMixin

class User(AbstractBaseUser, PermissionsMixin):
 '''

 '''

  username = models.CharField(max_length=50, null=True)
  first_name =models.CharField(max_length=50, null=True)
  last_name = models.CharField(max_length=50, null=True)
  email = models.EmailField(unique=True)
  is_active = models.BooleanField(default=True)
  is_staff = models.BooleanField(default=False)  
  date_joined = models.DateTimeField(default=timezone.now)

  USERNAME_FIELD = 'email'
  REQUIRED_FIELDS = ['username', ]
  objects = UserManager()

2 Comments

I am using django 1.10 version. And I am using AbstractUser not AbstractBaseUser. However does not it require usermanager implementation?
@Naroju , Now you are using AbstractBaseUser & you need UserManager too.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.