Can't log in super users created on the django admin backend - python

I'm trying to create superusers on the django admin backend, but somehow I can't get them to log in.
Here's my user class,
class User(AbstractBaseUser, PermissionsMixin):
email = models.EmailField(unique=True, max_length=255)
mobile = PhoneNumberField(null=True)
username = models.CharField(null=False, unique=True, max_length=255)
full_name = models.CharField(max_length=255, blank=True, null=True)
is_staff = models.BooleanField(default=False)
is_superuser = models.BooleanField(default=False)
is_active = models.BooleanField(default=False)
USERNAME_FIELD = 'email'
REQUIRED_FIELDS = ['username']
objects = UserManager()
Here's the UserManager function to create super user,
class UserManager(BaseUserManager):
def create_user(self, email, mobile=None, username=None, full_name=None, gender=None, birthday=None, password=None,
is_staff=False,
is_superuser=False, is_active=False, is_mobile_verified=False, is_bot=False, is_online=False,
is_logged_in=True):
if not email:
raise ValueError("Can't create User without a mobile number!")
if not password:
raise ValueError("Can't create User without a password!")
user = self.model(
email=self.normalize_email(email),
mobile=mobile,
username=username,
full_name=full_name,
gender=gender,
birthday=birthday,
is_staff=is_staff,
is_superuser=is_superuser,
is_active=is_active,
)
user.set_password(password)
return user
def create_superuser(self, email, username, password=None):
user = self.create_user(
email,
username=username,
password=password,
is_staff=True,
is_superuser=True,
is_active=True,
)
user.save(self._db)
return user
#property
def is_superuser(self):
return self.is_superuser
#property
def is_staff(self):
return self.is_staff
#property
def is_active(self):
return self.is_active
#property
def is_mobile_verified(self):
return self.is_mobile_verified
def has_perm(self, perm, obj=None):
return self.is_staff or self.is_superuser
def has_module_perms(self, app_label):
return self.is_staff or self.is_superuser
#is_staff.setter
def is_staff(self, value):
self._is_staff = value
#is_superuser.setter
def is_superuser(self, value):
self._is_superuser = value
#is_active.setter
def is_active(self, value):
self._is_active = value
Here's the relevant backend settings.
OAUTH2_PROVIDER = {
# this is the list of available scopes
'ACCESS_TOKEN_EXPIRE_SECONDS': 60 * 60 * 24,
'SCOPES': {'read': 'Read scope', 'write': 'Write scope', 'groups': 'Access to your groups'},
'OAUTH2_BACKEND_CLASS': 'oauth2_provider.oauth2_backends.JSONOAuthLibCore',
}
AUTHENTICATION_BACKENDS = (
'django.contrib.auth.backends.ModelBackend',
)
# REST Framework
REST_FRAMEWORK = {
'DEFAULT_AUTHENTICATION_CLASSES': (
'oauth2_provider.contrib.rest_framework.OAuth2Authentication',
),
'DEFAULT_PERMISSION_CLASSES': (
'rest_framework.permissions.IsAuthenticated',
),
}
I'm checking the is_staff and is_superuser to true on the creation form, still nothing. The created super user can't log in on the admin backend.
What am I doing wrong here.

First,
you are using custom user model. In your settings file, do you tell django to use your model instead of default auth.models.User ?
Second,
you are calling self.create_user inside your create_superuser function.
Do you override the create_user function as well ?
If yes, please provide the implementation.
Update
You dont need to change implementation user mansger's functions as you did.
IF you look at implementation of UserManger in django.auth.models. You can take inspiration from there and you avoid making a mistake - for example: you dont save model when you create standard user as you dont call save method.
I suggest to change your UserManager like this:
class UserManager(BaseUserManager):
use_in_migrations = True
def _create_user(self, email, password,
**extra_fields):
if not email:
raise ValueError('The given email must be set')
email = self.normalize_email(email)
user = self.model(email=email, **extra_fields)
user.set_password(password)
user.save(using=self._db)
return user
def create_user(self, email, password=None, **extra_fields):
extra_fields.setdefault('is_staff', False)
extra_fields.setdefault('is_superuser', False)
extra_fields.setdefault('is_active', False)
return self._create_user(email, password, **extra_fields)
def create_superuser(self, email, password, **extra_fields):
extra_fields.setdefault('is_staff', True)
extra_fields.setdefault('is_superuser', True)
if extra_fields.get('is_staff') is not True:
raise ValueError('Superuser must have is_staff=True.')
if extra_fields.get('is_superuser') is not True:
raise ValueError('Superuser must have is_superuser=True.')
return self._create_user(email, password, **extra_fields)

I created a new project with your code and I cannot reproduce your problem. Everything works fine on my side. However, I do notice a few things about your code:
First, in your settings.py, make sure you have set AUTH_USER_MODEL to your_app.User.
Second, in your UserManager class, I found things this:
#property
def is_staff(self):
return self.is_staff
This looks like an error to me, as it would produces infinite recursions. I guess in your case, there is a catch-all clause in django's code so the RecursionError is silenced. This may very likely be the problem.

Related

create a superuser and adminuser using django restframework

i have a custom user model and i want to create a superuser from a view right, am currently using django restframework, below is my custom model and serializer with the views.
model.py
class CompanyUserManager(UserManager):
def _create_user(self, username, email, password, **extra_fields):
"""
Create and save a user with the given username, email and passsword
"""
if not username:
raise ValueError('The given username must be set')
if not email:
raise ValueError('The email must be set')
email = self.normalize_email(email)
username = self.model.normalize_username(username)
user = self.model(username=username, email=email, **extra_fields)
user.set_password(password)
user.save(using=self._db)
return user
def create_user(self, username: str, email, password, **extra_fields):
extra_fields.setdefault('is_staff', True)
extra_fields.setdefault('is_superuser', False)
return self._create_user(username, email, password, **extra_fields)
def create_admin_user(self, username: str, email, password, **extra_fields):
extra_fields.setdefault('is_staff', True)
extra_fields.setdefault('is_superuser', False)
extra_fields.setdefault('is_admin', True)
# if extra_fields.get('is_staff') is not True:
# raise ValueError('Super user must have is_staff=True')
# if extra_fields.get('is_admin') is not True:
# raise ValueError('Super user must have is_admin=True')
# if extra_fields.get('is_superuser') is True:
# raise ValueError('Superuser must have is_superuser=False')
return self._create_user(username, email, password, **extra_fields)
def create_superuser(self, username: str, email, password, **extra_fields):
extra_fields.setdefault('is_staff', True)
extra_fields.setdefault('is_superuser', True)
extra_fields.setdefault('is_admin', True)
if extra_fields.get('is_staff') is not True:
raise ValueError('Super user must have is_staff=True')
if extra_fields.get('is_admin') is not True:
raise ValueError('Super user must have is_admin=True')
if extra_fields.get('is_superuser') is not True:
raise ValueError('Superuser must have is_superuser=True')
return self._create_user(username, email, password, **extra_fields)
# Create your models here.
class CompanyUser(AbstractBaseUser, PermissionsMixin):
username_validator = UnicodeUsernameValidator()
username = models.CharField(_('username'), max_length=150, unique=True, help_text='Required, 150 characters or fewer', error_messages={'unique ': ' a User with this user name is already registered'}, validators=[username_validator])
email = models.EmailField(_('email address'), blank=False, unique=True)
phone = models.CharField(_('phone'), max_length=20, blank=True, null=True)
is_staff = models.BooleanField(_('staff status'), default=True, help_text='Designated user can login using this account')
is_active = models.BooleanField(_('active'), default=True, help_text='Designated whether this user should be treated as active')
is_superuser = models.BooleanField(_('superuser'), default=False, help_text='Designated user can login using this account')
is_admin = models.BooleanField(_('admin'), default=False, help_text='Designated user can login using this account')
date_joined = models.DateTimeField(_('date joined'), default=timezone.now)
email_verified = models.BooleanField(_('email_verified'), default=False,)
objects = CompanyUserManager()
EMAIL_FIELD = 'email'
USERNAME_FIELD: str = 'email'
REQUIRED_FIELDS = ['username', 'phone']
#property
def token(self):
token = jwt.encode({
'username': self.username,
'email': self.email,
'exp': datetime.utcnow() + timedelta(hours=24)},
settings.SECRET_KEY, algorithm='HS256')
return token
#property
def staff(self):
return self.is_staff
#property
def admin(self):
return self.is_admin
#property
def active(self):
return self.is_active
#property
def owner(self):
return self.is_superuser
serializer.py
class RegisterSerializer(serializers.ModelSerializer):
# username = serializers.CharField(max_length=100)
# email = serializers.EmailField()
# password = serializers.CharField(max_length=100)
# password2 = serializers.CharField(max_length=100)
# def validate(self, data):
# if data['password'] != data['password2']:
# raise serializers.ValidationError('Passwords must match')
# return data
password = serializers.CharField(max_length=100, write_only=True)
class Meta:
model = CompanyUser
fields = ("id", "username", "email", "password", "is_active")
extra_kwargs = {"password": {"write_only": True}}
def create(self, validated_data):
user = CompanyUser(**validated_data)
user.set_password(validated_data["password"])
user.save()
return user
def create_superuser(self, validated_data):
user = CompanyUser(**validated_data)
print(validated_data)
if "password" in validated_data:
from django.contrib.auth.hashers import make_password
validated_data["password"] = make_password(validated_data["password"])
user.set_password(validated_data["password"])
user.is_superuser = True
user.is_admin = True
user.is_staff = True
user.save()
return user
the create_superuser isnt working, it throws a keyerror password not found
view.py
class RegisterAPIView(GenericAPIView):
"""
A view that allow company owners to create an account
"""
serializer_class = RegisterSerializer
def post(self, request, *args, **kwargs):
serializers = self.serializer_class(data=request.data)
if serializers.is_valid():
serializers.save()
# self.serializer_class.create_superuser(serializers.data)
# serializers.create_superuser(serializers.data)
return Response(serializers.data, status=status.HTTP_201_CREATED)
return Response(serializers.errors, status=status.HTTP_400_BAD_REQUEST)
so this are my codes and i cant create a superuser from the endpoint, i dont want to use the django cli, any help please 😌

TypeError: User() got an unexpected keyword argument 'is_staff' when using CustomUser

I am Creating a Custom User using AbstractBaseUser, but anytime I try to create a superuser, it says
TypeError: User() got an unexpected keyword argument 'is_staff'
user=self._create_user(email, password, True, True, **extra_fields)
File "C:\Users\user1\django\customuserproject\users\models.py", line 24, in _create_user
How do I solve this problem? I have checked other StackOverflow posts on this issue, but they didn't help me. I haven't tried with a regular user yet (I need a superuser to create a regular user), but I am sure it would be the same thing
My models.py:
class UserManager(BaseUserManager):
def _create_user(self, email, password, is_staff, is_superuser, **extra_fields):
if not email:
raise ValueError('Users must have an email address')
now = timezone.now()
email = self.normalize_email(email)
user = self.model(
email=email,
is_staff=is_staff,
is_active=True,
is_superuser=is_superuser,
last_login=now,
date_joined=now,
**extra_fields
)
#user.set_password(password)
user.save(using=self._db)
return user
def create_user(self, email, password, **extra_fields):
"""
Creates and saves a User with the given email and password.
"""
return self._create_user(email, password, False, False, **extra_fields)
def create_staffuser(self, email, password, **extra_fields):
"""
Creates and saves a staff user with the given email and password.
"""
user=self._create_user(email, password, True, False, **extra_fields)
user.save(using=self._db)
return user
def create_superuser(self, email, password, **extra_fields):
"""
Creates and saves a superuser with the given email and password.
"""
user=self._create_user(email, password, True, True, **extra_fields)
user.save(using=self._db)
return user
class User(AbstractBaseUser, PermissionsMixin):
email = models.EmailField(
verbose_name='email address',
max_length=255,
unique=True,
)
first_name = models.CharField(max_length=70, null=True, blank=True)
last_name = models.CharField(max_length=70, null=True, blank=True)
display_name = models.CharField(('display name'), max_length=70, blank=True, null=True, unique=False)
is_active = models.BooleanField(default=True)
is_staff = models.BooleanField(default=False) # a admin user; non super-user
is_superuser = models.BooleanField(default=False) # a superuser
last_login = models.DateTimeField(null=True, blank=True)
date_joined = models.DateTimeField(auto_now_add=True)
# notice the absence of a "Password field", that is built in.
objects = UserManager()
USERNAME_FIELD = 'email'
EMAIL_FIELD = 'email'
REQUIRED_FIELDS = ['first_name', 'last_name'] # Email & Password are required by default.
class Meta:
verbose_name = ('user')
verbose_name_plural = ('users')
#db_table = 'auth_user'
abstract = False
def get_absolute_url(self):
return "/users/%i/" % (self.pk)
#property
def name(self):
if self.first_name:
return self.first_name
elif self.display_name:
return self.display_name
return 'You'
def get_full_name(self):
"""
Return the first_name plus the last_name, with a space in between.
"""
full_name = '%s %s' % (self.first_name, self.last_name)
return full_name.strip()
def get_short_name(self):
return self.first_name
def email_user(self, subject, message, from_email=None):
send_mail(subject, message, from_email, [self.email])
def __str__(self):
return self.email
def natural_key(self):
return (self.email,)
def has_perm(self, perm, obj=None):
return True
def has_module_perms(self, app_label):
return True
#property
def is_staff(self):
return self.is_staff
#property
def is_superuser(self):
return self.is_superuser
#property
def is_active(self):
return self.is_active
Try using getter and setters with #property they work a lot better and are clearly implemented.
class Demo:
def __init__(self):
self._age = 0
# using property decorator
# a getter function
#property
def age(self):
print("getter method called")
return self._age
# a setter function
#age.setter
def age(self, a):
if(a < 18):
raise ValueError("Sorry you age is below eligibility criteria")
print("setter method called")
self._age = a
  
Thanks #Iain Shelvington, #Willem Van Onsem, and #7u5h4r.
I solved the problem by removing all the properties I declared, while leaving only the variables: is_staff, is_superuser, is_active.

TypeError: create_superuser() got an unexpected keyword argument 'email'

I need to create custom user model because I need to have one additional field called role. If the role is provided, it should be assigned to the user model otherwise provide agent as role in user model. I inherited the AbstractUser. This way when creating the user, first the password is saved as plain text and another is user cannot login it says unable to login. So i tried the below way as in docs but the problem is i don't need the email part so i excluded it and used just username and password but getting error like TypeError: create_superuser() got an unexpected keyword argument 'email'
class UserManager(BaseUserManager):
def create_user(self, username, password=None):
"""
Creates and saves a User with the given username, date of
birth and password.
"""
if not username:
raise ValueError('Users must have an username')
user = self.model(username=username)
user.set_password(password)
user.save(using=self._db)
return user
def create_superuser(self, username, password):
"""
Creates and saves a superuser with the given username and password.
"""
user = self.create_user(
username=username,
password=password,
)
user.is_admin = True
user.save(using=self._db)
return user
class Role(models.Model):
ROLE_CHOICES = (
('agent', 'Agent'),
('agency', 'Agency'),
('manufacturer', 'Manufacturer'),
)
role = models.CharField(max_length=15, choices=ROLE_CHOICES)
def __str__(self):
return self.role
class User(AbstractUser):
role = models.ForeignKey(
Role,
on_delete=models.CASCADE,
blank=True,
null=True,
)
objects = UserManager()
def __str__(self):
return self.username
#receiver(models.signals.post_save, sender=User)
def add_role_to_user(sender, instance, **kwargs):
print('instance in add role', instance)
if kwargs.get('created'):
try:
role = Role.objects.get(user=instance)
print('role', role)
except Role.DoesNotExist:
Role.objects.create(role="agent")
try:
token = Token.objects.get(user=instance)
print('token', token)
except Token.DoesNotExist:
Token.objects.create(user=instance)
Since you are not using email in create_superuser() you can add email as a keywork parameter and set to a None as
def create_superuser(self, username, password, email=None):
"""
Creates and saves a superuser with the given username and password.
"""
user = self.create_user(
username=username,
password=password,
)
user.is_superuser = True
user.save(using=self._db)
return user
you can just add *args, **kwargs in the function.
like this
def create_superuser(self, username, password, *args, **kwargs):
"""
Creates and saves a superuser with the given username and password.
"""
user = self.create_user(
username=username,
password=password,
)
user.is_superuser = True
user.save(using=self._db)
return user

django post_signal triggered on form.save(commit=False)

I have a base User model and two other models Candidate and Company
User:
email
password
is_company => default=False
Form class:
class CustomUserCreationForm(forms.Form):
email = forms.EmailField(label='Enter email', widget=forms.EmailInput(attrs={'placeholder': 'Email Address', 'spellcheck':'False', 'autofocus':'True'}))
password = forms.CharField(label='Enter password', min_length=8, widget=forms.PasswordInput(attrs={'placeholder': 'Password'}))
def clean_email(self):
email = self.cleaned_data['email'].lower()
r = User.objects.filter(email=email)
if r.count():
raise ValidationError("Email already exists")
return email
def clean_password(self):
password = self.cleaned_data.get('password')
return password
def save(self, commit=True):
user = User.objects.create_user(
self.cleaned_data['email'],
self.cleaned_data['password']
)
return user
My UserManager:
class UserManager(BaseUserManager):
use_in_migrations = True
def _create_user(self, email, password, **extra_fields):
"""
Creates and saves a User with the given email and password.
"""
try:
validate_email(email)
valid_email = True
except ValidationError:
valid_email = False
if not valid_email:
raise ValueError('Valid Email is required')
email = self.normalize_email(email)
user = self.model(email=email, **extra_fields)
user.set_password(password)
user.save(using=self._db)
subject = 'Activate Your Account'
message = render_to_string('registration/account_activation_email.html', {
'domain': 'example.in',
'user': user,
'uid': urlsafe_base64_encode(force_bytes(user.pk)),
'token': account_activation_token.make_token(user),
})
user.email_user(subject, 'example <admin#example.in>', html_message=message)
return user
def create_user(self, email, password=None, **extra_fields):
extra_fields.setdefault('is_superuser', False)
return self._create_user(email, password, **extra_fields)
def create_superuser(self, email, password, **extra_fields):
extra_fields.setdefault('is_superuser', True)
if extra_fields.get('is_superuser') is not True:
raise ValueError('Superuser must have is_superuser=True.')
return self._create_user(email, password, **extra_fields)
In my user creation view:
class SignUpView(View):
is_company = False
def get(self, request):
if request.user.is_authenticated():
return redirect(reverse_lazy('dashboard'))
form = CustomUserCreationForm()
return render(request, 'registration/signup.html', {'form': form, 'is_company':self.is_company})
def post(self,request):
form = CustomUserCreationForm(request.POST or None, request.FILES or None)
if form.is_valid():
user = form.save(commit=False)
user.is_active = False
user.is_company = self.is_company
user.save()
return render(request, 'registration/account_activation_sent.html')
return render(request, 'registration/signup.html', {'form': form, 'is_company':self.is_company})
I have created a post_save signal for the above model.
#receiver(post_save, sender=User)
def update_user_profile(sender, instance, created, **kwargs):
if created:
if instance.is_company:
Company.objects.create(user=instance)
instance.company.save()
else:
Candidate.objects.create(user=instance,
first_name=instance.is_company )
instance.candidate.save()
urls.py:
url(r'^accounts/signup/company/',vw.SignUpView.as_view(is_company = True), name='signup_company')
The problem is the form.save(commit=False) is triggering the post_save signal. I end up having instance.is_company as False, thus creating a CandidateProfile for a Company.
But the the database user table is populated with is_company as True for the company.
Please help!
You should try disconnecting the post_save signal before working on your instance and connecting it later.
#receiver(post_save, sender=User)
def update_user_profile(sender, instance, created, **kwargs):
# disconnect post_save
post_save.disconnect(update_user_profile, sender=sender)
# do something with your instance
# connect post_save
post_save.connect(update_user_profile, sender=sender)
In your form you have overridden save and are always calling create_user which will call user.save(using=self._db) i.e not passing the value of commit
What you can do is override _create_user in your User model to pass the value of commit to it
class User(AbstractBaseUser):
...
def _create_user(self, username, email, password, commit=True, **extra_fields):
if not username:
raise ValueError('The given username must be set')
email = self.normalize_email(email)
username = self.model.normalize_username(username)
user = self.model(username=username, email=email, **extra_fields)
user.set_password(password)
if commit:
user.save(using=self._db)
return user
And then in your form you can pass the value of commit to it
class CustomUserCreationForm(forms.Form):
def save(self, commit=True):
return User.objects.create_user(
self.cleaned_data['email'],
self.cleaned_data['password'],
commit=False
)
Edit: Looking into this code again, I feel it is bad.
You're better off fixing your logic in the form to do multiple saves
class CustomUserCreationForm(forms.Form):
def save(self, commit=True):
is_create = self.instance.pk is None
user = super().save(commit=commit)
user.set_password(self.cleaned_data['password'])
user.save()
if not is_create:
return user
if user.is_company:
Company.objects.create(user=user)
user.company.save() # not really needed
else:
Candidate.objects.create(user=user, first_name=user.is_company)
user.candidate.save() # not really needed
return user
P.S: I personally dislike django signal as they can cause confusion as to what is happening. It might be better to do this in your view or in the form save instead. You should have only one way of creating new users so it shouldn't be a big problem.
Change your argument to default False and check if this is true before saving... with your way doenst matter if you call it with commit false or true, they will always save in data base... so because of that they are triggers your post_save
def save(self, commit=False):
if commit:
user = User.objects.create_user(
self.cleaned_data['email'],
self.cleaned_data['password']
)

TypeError: create_user() got multiple values for keyword argument 'name'

I'm trying to create custom authentication in Django where the identifier is an email, there is a required field called name and a password field. While creating the superuser, i'm getting an error.
TypeError: create_user() got multiple values for keyword argument 'name'
Here is my models.py
from django.db import models
from django.contrib.auth.models import User
from django.conf import settings
from django.contrib.auth.models import (
BaseUserManager, AbstractBaseUser
)
class MyUserManager(BaseUserManager):
def create_user(self, name, email, password=None):
"""
Creates and saves a User with the given email, name and password.
"""
if not email:
raise ValueError('Users must have an email address')
user = self.model(
name=name,
email=self.normalize_email(email),
)
user.set_password(password)
user.save(using=self._db)
return user
def create_superuser(self, email, name, password):
"""
Creates and saves a superuser with the given email, name and password.
"""
user = self.create_user(email,
password=password,
name=name
)
user.is_admin = True
user.save(using=self._db)
return user
class MyUser(AbstractBaseUser):
email = models.EmailField(
verbose_name='email address',
max_length=255,
unique=True,
)
name = models.CharField(max_length=20)
is_active = models.BooleanField(default=True)
is_admin = models.BooleanField(default=False)
objects = MyUserManager()
USERNAME_FIELD = 'email'
REQUIRED_FIELDS = ['name']
def get_full_name(self):
# The user is identified by their email address
return self.email
def get_short_name(self):
# The user is identified by their email address
return self.email
# On Python 3: def __str__(self):
def __unicode__(self):
return self.name
def has_perm(self, perm, obj=None):
"Does the user have a specific permission?"
# Simplest possible answer: Yes, always
return True
def has_module_perms(self, app_label):
"Does the user have permissions to view the app `app_label`?"
# Simplest possible answer: Yes, always
return True
#property
def is_staff(self):
"Is the user a member of staff?"
# Simplest possible answer: All admins are staff
return self.is_admin
class MyUser(AbstractBaseUser):
name = models.CharField(max_length=20)
email = models.CharField(max_length=40, unique=True)
REQUIRED_FIELDS = ['name']
USERNAME_FIELD = 'email'
Here is the traceback
File "/usr/local/lib/python2.7/dist-packages/django/contrib/auth/management/commands/createsuperuser.py", line 141, in handle
self.UserModel._default_manager.db_manager(database).create_superuser(**user_data)
File "/home/jaskaran/coding/django/TaskMan/taskmanager/models.py", line 32, in create_superuser
name=name
TypeError: create_user() got multiple values for keyword argument 'name'
Change your function call
user = self.create_user(email,
password=password,
name=name
)
to
user = self.create_user(email=email, # use email=email
password=password,
name=name
)
The order of your parameters is not correct. The email is passed before name and then again name is passed as keyword parameter.
I got the answer, and this is how you frame your code
def create_superuser(self, email, name, password):
"""
Creates and saves a superuser with the given email, name and password.
"""
user = self.create_user(
email,
name,
password=password,
)
user.is_admin = True
user.save(using=self._db)
return user

Categories