Cannot login a normal user in a django website having a custom user model

3k Views Asked by At

I have made a Custom user model for my website. I have used AbstractBaseUser to make the model and also set it up at the settings. The creation of user and superuser is working fine without any problems and also a super user can login from the admin page. However when I am trying to make a normal user to login in the website is returns User none. But the normal user exists in the datatbase. I am using the authenticate to make a user login since I have used AbstractBaseUser. I am unable to unserstand why is this saying that the user doesn't exist. Please rectify me if I have written some wrong codes.

models.py (the custom user model), here the is_active is false but I manually activate it after regd so the problem is not because of this


class CustomUser(AbstractBaseUser, PermissionsMixin):
    
    email = models.EmailField( unique= True)
    full_name = models.CharField(max_length=255)
    phone_no = models.CharField(max_length=10, blank= True)
    address = models.CharField(max_length=500, blank= True)
    plan = models.CharField(max_length=255, blank= True)
    age = models.CharField(max_length=2, blank= True)

    date_joined = models.DateTimeField(default=timezone.now)




    is_staff = models.BooleanField( default=False)
    is_active = models.BooleanField( default=False)

    objects = CustomUserManager()


    USERNAME_FIELD = 'email'
    REQUIRED_FIELDS = ['full_name']


    def __str__(self):
        return self.email

managers.py (custom user model manager)

class CustomUserManager(BaseUserManager):

    # CUSTOM USER MODEL FOR USER WHERE EMAIL IS THE USERNAME FOR AUTHENTICATION RATHER THEN USERNAME

    
    
    def create_superuser(self, email, full_name, password, **other_fields):

    # CREATE AND SAVE SUPERUSER WITH THE GIVEN EMAIL AND PASSWORD

        other_fields.setdefault('is_staff', True)
        other_fields.setdefault('is_superuser', True)
        other_fields.setdefault('is_active', True)

        if other_fields.get('is_staff') is not True:
            raise ValueError(_('is staff must be set to true'))
        
        if other_fields.get('is_superuser') is not True:
            raise ValueError(_('is superuser must be set to true'))
        
        return self.create_user(email, full_name, password, **other_fields)

    
    def create_user(self, email,full_name, password, **other_fields):

    # CREATE AND SAVE USER WITH THE GIVEN EMAIL AND PASSWORD

        if not email:
            raise ValueError(_('The Email must be set'))
        
        email = self.normalize_email(email)
        user = self.model(email=email, full_name=full_name,**other_fields)
        user.set_password(password)
        user.save()
        return user

settings.py

AUTH_USER_MODEL = 'account.CustomUser'

views.py (function that hanndles the login and user creation)

def registerpage(request):

    if request.method == 'POST':
        full_name = request.POST['full_name']
        age = request.POST['age']
        phone_no = request.POST['phone']
        address = request.POST['address']
        plan = request.POST['plan']
        email = request.POST['email']
        password1= request.POST['password']
        password2= request.POST['con_password']

        if password1==password2:
            user=CustomUser.objects.create_user(full_name=full_name,age=age, phone_no=phone_no, address=address, plan=plan, email=email, password=password1)
            user.save()
            print('user created')
            return redirect('login')
    else:
        return render(request, 'register.html')

def loginpage(request):

    if request.method == 'POST':
        username = request.POST.get('username')
        password = request.POST.get('paswword')

        # user = CustomUser.objects.get(email=username, password=password)
        
        user = authenticate(request, email=username, password=password)

        if user is not None:
            login(request, user)
            return redirect(user_page) # this is in home views
        else:
            return HttpResponse(' User doesnt exist')               #FOR ERROR PURPOSE

    else:
        return render(request, 'login.html')



def t_and_c(request):
    return render(request, 'terms_and_condition.html')

This is the first time I am using a Custom model so I do not know whether I am using the correct way to login a user. Please correct me if I am wrong.

3

There are 3 best solutions below

0
On

From my observation of your code the form you submitting to the register view: the password is not hashed so automatically django will return user does not exist as response upon form submission because while creating the superuser from cmd password was hashed. Check your CustomUser to see if you did this: user.set_password(password). To cap it all try hashing your password field value in the login and registration views respectively.

Hopefully I think this will help someone.

0
On

Only staff and superusers are allowed to login to the admin by default.

Check the django.contrib.admin.forms.AdminAuthenticationForm

Is contains the following check:

def confirm_login_allowed(self, user):
    super().confirm_login_allowed(user)
    if not user.is_staff:
        raise ValidationError(
            self.error_messages['invalid_login'],
            code='invalid_login',
            params={'username': self.username_field.verbose_name}
        )
5
On

You have this error because you never activate the user (is_active=False) by default in the CustomUser model.

I also see that you don't have a view to activate the new user. Then what you need to do is to activate the user at the creation (registerpage) :

def registerpage(request):
    # Lot of code
    if password1==password2:
        user=CustomUser.objects.create_user(...)

        # You don't need to call save, as create_user do it already
        # user.save()

        # Now active the user
        user.is_active = True
        user.save()  # Here save() is necessary
       

More about Django User Model

UPDATE :

In your Custom Manager you set USERNAME_FIELD = 'email' That means, you need to provide email and password to login.

def loginpage(request):

    if request.method == 'POST':
        email = request.POST.get('email')
        password = request.POST.get('paswword')
        
        # Use eamail to authenticate instead of username
        user = authenticate(request, email=email, password=password)