There are two ways to solve your problem.
- Extend the User model by subclassing it, and changing the default User model. I would recommend you go this route, since the Phone number is used for authentication.
- Set related_name on Profile, and query the User model from that name.
For the first one, I recommend you check out the Django documentation on creating custom users.
There is also a pretty extensive tutorial on how to do this here.
If you want to go the easy route, you just need to set a reverse accessor on the Profile's phonenumber field.
class Profile(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
phonenumber = models.CharField(max_length=10, related_name='profile')
You can then search users by their profile's phonenumbers:
class AuthenticationBackend(backends.ModelBackend):
def authenticate(self, request, username=None, password=None, **kwargs):
usermodel = get_user_model()
print(usermodel)
try:
user = usermodel.objects.get(Q(username__iexact=username) | Q(
email__iexact=username) | Q(profile__phonenumber__iexact=username)
if user.check_password(password):
return user
except user.DoesNotExist:
pass
Although this is not within the scope of your question, I think you should be aware of the following issues with your code:
- Phone numbers are often more complex than a 10 character string. +31 6 12345678, is a valid phone number, but it's more than 10 characters. Check out this question for pointers on how to store and validate phone numbers.
- If you use a field for authentication, make sure it's unique. The phonenumber field should actually be
phonenumber = models.CharField(max_length=10, related_name='profile', unique=True)
- Your
usermodel.objects.get(...) query will return more than one user if there is a user with phone number '0123456789' and a different user with username '0123456789'. You should constrain usernames to not contain phone numbers, which is only possible by extending the default User class.