Issue with Django's LoginView after customizing User Model

I've encountered an issue after customizing Django's built-in User model (AbstractUser). I've created a custom user model named TheUser which inherits from AbstractUser. After making this change, the built-in LoginView from django.contrib.auth.views seems unable to authenticate users, even though the user data exists in the MySQL database.

Here's a simplified overview of my code structure:

models.py:

from django.db import models
from django.contrib.auth.models import AbstractUser
from phonenumber_field.modelfields import PhoneNumberField

# Create your models here.
choices = (
    ('M', 'Men'),
    ('F', 'Female'),
    ('P', 'Personnalised'),
)
class TheUser(AbstractUser):
    age = models.IntegerField(blank=True, null=True)
    genre = models.CharField(max_length=10, choices=choices, default='M')
    adress = models.OneToOneField('UserAdress', on_delete=models.CASCADE, null=True)
    phone_number = PhoneNumberField(null=True)

class UserAdress(models.Model):
    country = models.CharField(max_length=20)
    city = models.CharField(max_length=20)

I've defined a custom user model named TheUser which includes additional fields like age, genre, phone_number, and a one-to-one relationship with UserAdress.

urls.py:

from django.urls import path, include
from django.contrib.auth import views as auth_views
from .forms import userForm

form = userForm()
app_name = 'user'
urlpatterns = [
    path('login/', auth_views.LoginView.as_view(template_name='registration/login.html', context={'form': form}), name='login'),
    path('', include('django.contrib.auth.urls')),
]

The login URL is configured to use Django's LoginView with a custom login template (login.html). Other URLs for signup, logout, and profile are also defined.

forms.py:

from django import forms
from .models import TheUser
from phonenumber_field.widgets import PhoneNumberPrefixWidget

class userForm(forms.ModelForm):
    country = forms.CharField(max_length=50)
    city = forms.CharField(max_length=50)
    class Meta:
        model = TheUser
        fields = [
            'username',
            'first_name',
            'last_name',
            'email',
            'age',
            'genre',
            'phone_number',
            'password',
        ]
        widgets = {
            'phone_number': PhoneNumberPrefixWidget()
        }

I've defined a custom form named userForm to handle user registration. Additionally, there's a UserLoginForm which is a subclass of userForm specifically for login purposes.

auth_backends.py:

from django.contrib.auth import get_user_model
from django.contrib.auth.backends import BaseBackend

class UserBackend(BaseBackend):
    def authenticate(self, request, username=None, password=None, **kwargs):
        User = get_user_model()
        try:
            user = User.objects.get(username=username)
            if user.check_password(password):
                return user
        except User.DoesNotExist:
            return None

    def get_user(self, user_id):
        User = get_user_model()
        try:
            return User.objects.get(pk=user_id)
        except User.DoesNotExist:
            return None

I've implemented a custom authentication backend (UserBackend) to authenticate users based on the custom user model (TheUser).

login.html:

{% extends 'generic_base.html' %}
{% block content %}
    <h1 id="login-title">Login Page</h1>
    {% if form.errors %}
    <p>Your username and password didn't match. Please try again.</p>
    {% endif %}
    {% if next %}
        {% if user.is_authenticated %}
            <p>Your account doesn't have access to this page. To proceed,
            please login with an account that has access.</p>
            {% else %}
                <p>Please login to see this page.</p>
            {% endif %}
    {% endif %}
    <form id="login-form" method='post'>
        {% csrf_token %}
        <table>
            <tr>
                <td>{{ form.username.label_tag }}</td>
                <td>{{ form.username }}</td>
            </tr>
            <tr>
                <td>{{ form.password.label_tag }}</td>
                <td>{{ form.password }}</td>
            </tr>
            <input type='submit' value='login'>
            <input type='hidden' name='next' value='{{ next }}'>
        </table>
    </form>
{% endblock content %}

This is the custom login template used by the LoginView. It includes form fields for username and password.

Despite implementing these changes, when attempting to log in using the LoginView, it fails to authenticate users, showing errors like "Your username and password didn't match. Please try again."

I'm seeking assistance in troubleshooting this issue and understanding why the LoginView is unable to authenticate users after customizing the User model.

Any insights or suggestions would be greatly appreciated. Thank you!

Back to Top