'Django authenticate() always return None for a custom model

I'm new to django, and I have to make a back-end with it. my issue: I have multiple models (clients,driver,company) all of them should login and authenticate (each one on a diffrent app, but they all extend the same user model), i have seen so many questions like this, but none of them solved my issue which is authenticate(username='username',password='password') always return none. the user record exists in the DB, i checked it with filter(username=(username). so here is some code:

The UserManager class:

class UserManager(BaseUserManager):

def create_user(self, username, password, phone):
    if not username:
        raise ValueError("user must provide a username")
    if not password:
        raise ValueError("user must provide a password")
    if not phone:
        raise ValueError("user must povide a phone number")

    user_obj = self.model(
        user_name=username,
        phone=phone
    )
    user_obj.set_password(password)
    user_obj.save()
    return user_obj

the User class:

class User(AbstractBaseUser):
    user_name = models.CharField(max_length=32, unique=True)
    email = models.EmailField(max_length=255, unique=True, null=True)
    phone = PhoneNumberField()
    access_token = models.CharField(max_length=255, unique=True, null=True)
    notifications_token = models.CharField(max_length=255, unique=True, null=True)
    photo = models.ImageField()
    person_in_contact = models.CharField(max_length=32)
    active = models.BooleanField(default=False)
    confirmedEmail = models.BooleanField(default=False)
    confirmedPhone = models.BooleanField(default=False)
    completedProfile = models.BooleanField(default=False)

    objects = UserManager()

    @property
    def is_active(self):
        return self.active

    def __str__(self):
        return "Client : " + self.user_name + " Email:" + self.email

    def get_email(self):
        return self.email

    USERNAME_FIELD = 'user_name'

    REQUIRED_FIELDS = ['username', 'phone', 'password']

    class Meta:
        abstract = True

Person class (client and driver extends from this):

class Person(User):
    GENDER = (('F', 'FEMALE'), ('M', 'MALE'))

    name = models.CharField(max_length=50, null=True)
    surname = models.CharField(max_length=50, null=True)
    adress = models.CharField(max_length=255, null=True)
    birth_date = models.DateField(null=True)
    gender = models.CharField(max_length=1, choices=GENDER, default='M')

    def age(self):
        today = date.today()
        return today.year - self.birth_date.year

    def __str__(self):
        return super().__str__() + " Name : " + self.name

    class Meta:
        abstract = True

here is the driver model that i'm testing with (if this succeed i'll apply the same method to the 2 other models):

class Driver(Person):
    rating = models.DecimalField(default=0, decimal_places=1, max_digits=3)
    driving_license = models.CharField(max_length=50, null=True)
    insurance_number = models.CharField(max_length=50, null=True)
    company = models.ForeignKey(TransportCompany, on_delete=models.DO_NOTHING, null=True)

my settings.py folder is setup:

AUTHENTICATION_BACKENDS = (
'django.contrib.auth.backends.ModelBackend',
)

AUTH_USER_MODEL = 'drivers.Driver'

and here is how i test in the python console:

>>> from django.contrib.auth import authenticate
>>> print (authenticate(username='Simouchee',password='123456789'))
None

and when i test with filter and exists:

>>> driver = Driver.objects.filter(user_name = 'Simouchee')
>>> driver.exists()
True

any help/hint on how authenticate custom models properly is appreciated. really sorry for the long thread i felt the need of explaining in details.



Solution 1:[1]

You have a mistake here authenticate(username='Simouchee',password='123456789')

You have user_name in your model, but username in authenticate call.

I would say, that it's preferable to have username without underscore in your model in the same fashion as in django framework itself - https://github.com/django/django/blob/master/django/contrib/auth/models.py#L299

Also check password as mentioned here - Django authenticate() always return None for a custom model

Edited: Issue can be in User model. You have default=False for field active, so check also if your user is active. Since ModelBackend checks is_active in method user_can_authenticate - https://github.com/django/django/blob/master/django/contrib/auth/backends.py#L51

Solution 2:[2]

Sounds like there is no issue with your code. Django built-in function of Authenticate works perfectly, make sure if the user is created properly.

If you are using this to create a user:

user = User.objects.create(username=username, password=user_password, email=user_email)

It will create User but, it might not authenticate. It will return None, it happened with me too.

Please try this:

user = User.objects.create_user(username=username, password=user_password, email=user_email) user.save()

Then try authenticate(username=username, password=password) It should work!

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1
Solution 2 Raza ul Mustafa