DISQUS

David Cramer's Blog: Logging In With Email Addresses in Django

  • sean · 1 year ago
    wow, it's the piece of code i'm trying to get.
    thanks for posting it, again!
  • gnrfan · 1 year ago
    Yes, Django is flexible enought to permit this just by adding this small piece of code.

    One quirk arises when logging in with an email address in the admin site: if the authentication does not success for any reason you'll get a "Usernames cannot contain the '@' character." error message which is misleading because Django is having no problem to log you in using an email address at this point.

    So to correct that you should override the login() method of the admin object as pointed out by James Bennet in this bug:

    http://code.djangoproject.com/ticket/8342

    Antonio,
    Lima - Peru
  • gnrfan · 1 year ago
    I just tried the code and realized the backend is missing the other methods that ModelBackend implements so I made EmailOrUsernameModelBackend inherint from ModelBackend instead of object and now everything works like a charm.

    The code is here at PasteThat:

    http://www.pastethat.com/django_email_login

    Regards,

    Antonio
  • David Cramer · 1 year ago
    Ya I did notice that get_user is still required. I updated the above code.

    The reason it doesn't inherit from ModelBackend is that this allows you to specify a second backend to use for permissions.
  • julien · 1 year ago
    Hey, just a quick note. If using the standard login views, you won't be able to login with an email that's longer than 30 characters. There's a ticket with a simple patch which hopefully will get checked in to fix that:
    http://code.djangoproject.com/ticket/8274

    Cheers,

    Julien Phalip
  • carljm · 1 year ago
    > The reason it doesn’t inherit from ModelBackend is that this allows you to specify a second backend to use for permissions.

    Could you expand on this? I've been using an EmailBackend similar to yours, except that it inherits from ModelBackend, overrides only the authenticate() method, and I use it all by itself in AUTHENTICATION_BACKENDS. This seems to work just fine. What am I missing that your approach provides?