Django inbuilt Auth not logging me in despite successfully registering the user

hello!
i would like to login after registering a user that is saved using my customuser model that exends abstractuser. the customuser model simply additional fields. (i.e. is_active, is_agency)
after registering the user, i redirect them to the login page.
and when i try to login the user with the credentials that is just created, it will say

__ all __
Please enter a correct username and password. Note that both fields may be case-sensitive.

i am not sure why the backends is throwing this error, i have tried looking into the authenticationform that i extended as well as the save and create_user.
just wondering is it better if i created a userprofile model instead of extending the default django user model for this use case?
do i need a custom backend authentication? (which i would like to avoid…)

here is my models.py

class CustomUserManager(BaseUserManager):
    def create_user(self, email, username, first_name, last_name, password, **other_fields):
        print('in customusermanager create_user')
        if not email:
            raise ValueError(gettext_lazy('You must provide a valid email address'))
        email = self.normalize_email(email)
        user = self.model(email=email, username=username, first_name=first_name, last_name=last_name, **other_fields)
        user.set_password(password)
        user.save()
        return user

    def create_superuser(self, email, username, first_name, last_name, password, **other_fields):
        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('Superuser %s must be assigned to is_staff=True' % (username))
        if other_fields.get('is_superuser') is not True:
            raise ValueError('Superuser %s must be assigned to is_superuser=True' % (username))
        
        return self.create_user(email, username, first_name, last_name, password, **other_fields)
        
class CustomUser(AbstractUser, PermissionsMixin):
    email = models.EmailField(gettext_lazy('email address'), unique=True)
    username = models.CharField(max_length=150, unique=True)
    first_name = models.CharField(max_length=150, unique=True)
    last_name = models.CharField(max_length=150, unique=True)
    start_date = models.DateTimeField(default=timezone.now)
    about = models.TextField(gettext_lazy('about'), max_length=500, blank=True)
    is_staff = models.BooleanField(default=False)
    is_active = models.BooleanField(default=False) # user account will not be active upon creation. TODO: add sending email to user to activate then can login
    is_agency = models.BooleanField(default=False)

    objects = CustomUserManager()

    REQUIRED_FIELDS = ['email', 'first_name', 'last_name']

    def __str__(self):
        return self.username

and here is my forms.py

class RegistrationForm(UserCreationForm):
    class Meta:
        model = CustomUser
        fields = ('email', 'username', 'first_name', 'last_name', 'password1', 'password2', 'is_agency')
    
    email = forms.CharField(widget=forms.EmailInput(attrs={
        'placeholder': 'Your email',
        'class': 'bg-gray-50 border border-gray-300 text-gray-900 sm:text-sm rounded-lg focus:ring-primary-600 focus:border-primary-600 block w-full p-2.5 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-white dark:focus:ring-blue-500 dark:focus:border-blue-500'
    }))

    username = forms.CharField(widget=forms.TextInput(attrs={
        'placeholder': 'Your username',
        'class': 'bg-gray-50 border border-gray-300 text-gray-900 sm:text-sm rounded-lg focus:ring-primary-600 focus:border-primary-600 block w-full p-2.5 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-white dark:focus:ring-blue-500 dark:focus:border-blue-500'
    })) 

    first_name = forms.CharField(widget=forms.TextInput(attrs={
        'placeholder': 'Your first name',
        'class': 'bg-gray-50 border border-gray-300 text-gray-900 sm:text-sm rounded-lg focus:ring-primary-600 focus:border-primary-600 block w-full p-2.5 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-white dark:focus:ring-blue-500 dark:focus:border-blue-500'
    })) 

    last_name = forms.CharField(widget=forms.TextInput(attrs={
        'placeholder': 'Your last name',
        'class': 'bg-gray-50 border border-gray-300 text-gray-900 sm:text-sm rounded-lg focus:ring-primary-600 focus:border-primary-600 block w-full p-2.5 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-white dark:focus:ring-blue-500 dark:focus:border-blue-500'
    })) 

    password1 = forms.CharField(widget=forms.PasswordInput(attrs={
        'placeholder': '••••••••',
        'class': 'bg-gray-50 border border-gray-300 text-gray-900 sm:text-sm rounded-lg focus:ring-primary-600 focus:border-primary-600 block w-full p-2.5 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-white dark:focus:ring-blue-500 dark:focus:border-blue-500'
    }))

    password2 = forms.CharField(widget=forms.PasswordInput(attrs={
        'placeholder': '••••••••',
        'class': 'bg-gray-50 border border-gray-300 text-gray-900 sm:text-sm rounded-lg focus:ring-primary-600 focus:border-primary-600 block w-full p-2.5 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-white dark:focus:ring-blue-500 dark:focus:border-blue-500'
    }))
    
    is_agency = forms.BooleanField(required=False, widget=forms.CheckboxInput(attrs={
        'id': 'is_agency',
        'class': 'w-4 h-4 border border-gray-300 rounded bg-gray-50 focus:ring-3 focus:ring-primary-300 dark:bg-gray-700 dark:border-gray-600 dark:focus:ring-primary-600 dark:ring-offset-gray-800'
    }))

    def save(self):
        self.clean()
        user = self.Meta.model(
            username = self.cleaned_data['username'], 
            email = self.cleaned_data['email'], 
            password = self.cleaned_data['password2'], 
        )
        user.set_password(self.cleaned_data['password2'])
        user.save()
        return user

my views.py

def registration(request):
    if request.method == 'POST':
        form = RegistrationForm(request.POST)
        if form.is_valid():
            form.save()
            return redirect('/listing/login/')
    else:
        form = RegistrationForm()

    return render(request, 'listing/registration.html', {'form':form})

def login(request):
    if request.method == 'POST':
        form = LoginForm(request, data=request.POST)
        print(form.errors)
        if form.is_valid():
            
            username = form.cleaned_data.get('username')
            password = form.cleaned_data.get('password')
            user = authenticate(request, username=username, password=password)
            print(user)
            if user is not None:
                login(request, user)
                return redirect('/')
    else:
        form = LoginForm()
    return render(request, 'listing/login.html', {'form': form})

my registration.html

<form class="space-y-4 md:space-y-6" method="post">
    {% csrf_token %}
    <div>
        <label for="email" class="block mb-2 text-sm font-medium text-gray-900 dark:text-white">Email</label>
        {{ form.email }}
        {{ form.email.errors }}
    </div>
    <div>
        <label for="username" class="block mb-2 text-sm font-medium text-gray-900 dark:text-white">Username</label>
        {{ form.username }}
        {{ form.username.errors }}
    </div>
    <div>
        <label for="first_name" class="block mb-2 text-sm font-medium text-gray-900 dark:text-white">First Name</label>
        {{ form.first_name }}
        {{ form.first_name.errors }}
    </div>
    <div>
        <label for="last_name" class="block mb-2 text-sm font-medium text-gray-900 dark:text-white">Last Name</label>
        {{ form.last_name }}
        {{ form.last_name.errors }}
    </div>
    <div>
        <label for="password" class="block mb-2 text-sm font-medium text-gray-900 dark:text-white">Password</label>
        {{ form.password1 }}
        {{ form.password1.errors }}
    </div>
    <div>
        <label for="confirm_password" class="block mb-2 text-sm font-medium text-gray-900 dark:text-white">Confirm password</label>
        {{ form.password2 }}
        {{ form.password2.errors }}
    </div>
    <div class="flex items-start">

        <div class="flex items-center h-5">
            {{ form.is_agency }} 
        </div>
        <div class="ml-3 text-sm">
            <label for="is_agency" class="font-light text-gray-500 dark:text-gray-300">Are you an Employment Agent?</label>
        </div>
        {{ form.errors }}
        <!--<div class="flex items-center h-5">
            <input id="terms" aria-describedby="terms" type="checkbox" class="w-4 h-4 border border-gray-300 rounded bg-gray-50 focus:ring-3 focus:ring-primary-300 dark:bg-gray-700 dark:border-gray-600 dark:focus:ring-primary-600 dark:ring-offset-gray-800" required="">
        </div>
        <div class="ml-3 text-sm">
            <label for="terms" class="font-light text-gray-500 dark:text-gray-300">I accept the <a class="font-medium text-primary-600 hover:underline dark:text-primary-500" href="#">Terms and Conditions</a></label>
        </div>-->
    </div>
    <button type="submit" class="w-full text-white bg-primary-600 hover:bg-primary-700 focus:ring-4 focus:outline-none focus:ring-primary-300 font-medium rounded-lg text-sm px-5 py-2.5 text-center dark:bg-primary-600 dark:hover:bg-primary-700 dark:focus:ring-primary-800">Create an account</button>
    <p class="text-sm font-light text-gray-500 dark:text-gray-400">Already have an account? 
        <a href="# " class="font-medium text-primary-600 hover:underline dark:text-primary-500">Login here</a>
    </p>
</form>

Did you configure your CustomUser model in the AUTH_USER_MODEL setting?

Also, in your RegistrationForm, you have:
fields = ('email', 'username', 'first_name', 'last_name', 'password1', 'password2', 'is_agency')

But, password1 and password2 are not fields in the model. There’s no need to specify them there.

1 Like

Hi Ken!
Thanks for the comment, I have found the issue!
it was because i had assumed is_active was a variable that was controlled by me because i just wrote it in, but actually it was being used by django. i noticed this when i dived deeper into the documentation here: django.contrib.auth | Django documentation | Django
basically i set is_active to false as default so it wouldn’t let the newly created user login.

to answer your question, yes i had added listing.CustomUser to AUTH_USER_MODEL as well.

Pertaining to your comment on my RegistrationForm, can i get your opinion on whether i should include password1 and password2 in my model? I had wanted to use them as django intended it (password1 must equal password2 for confirmation)

No, they don’t need to be in the model. They shouldn’t be in the model. They can exist solely as form fields.

1 Like

i see. thank you so much! i will mark this as closed then!

Cheers!