Last Updated: September 09, 2019
·
1.03K
· hartleybrody

Django Friendly Logins

By default, Django stores both a username and email field for each user. According to the docs, the authenticate() function in django.contrib.auth expects the user to login with a username, not an email address.

But what if someone accidentally tries to login using their email address. That should still get them logged in, right?

from django.contrib import auth
from django.contrib.auth.models import User
...
user = auth.authenticate(username=username, password=pwd)
if not user: 
    try:
        u = User.objects.get(email=username)
        user = auth.authenticate(username=u.username, password=pwd)
    except User.DoesNotExist:
        pass

if user is not None and user.is_active:
    auth.login(request, user)

If we're unable to authenticate them using the "username" they provide, try looking up a User with that as their email address, and then use that User's username to authenticate.

2 Responses
Add your response

To reduce the number of queries to the DB, you may first check if username contains an @ and query first by email, then fall to username.

It's more common an @ in the email than the username.

over 1 year ago ·

@leech To me, this feels like an unnecessary optimization. I could see it causing weird login edge cases that are hard to diagnose, and only for the sake of saving one database query on a login.

It is a good point that we could be smarter about determining whether it's an email or username, but I just see that stuff as being unnecessary for such a small savings, in this case.

over 1 year ago ·