Naroju
Naroju

Reputation: 2677

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)

Upvotes: 1

Views: 4295

Answers (3)

Apoorv Kansal
Apoorv Kansal

Reputation: 3290

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.

Upvotes: 4

Prakhar Trivedi
Prakhar Trivedi

Reputation: 8526

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.

Upvotes: 3

Ankush
Ankush

Reputation: 1874

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()

Upvotes: -2

Related Questions