Naroju Naroju - 1 month ago 31
Python Question

Cannot create super user in django

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)

Answer
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.