1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26 | from django.contrib.auth.models import User
from django.core.validators import email_re
class BasicBackend:
def get_user(self, user_id):
try:
return User.objects.get(pk=user_id)
except User.DoesNotExist:
return None
class EmailBackend(BasicBackend):
def authenticate(self, username=None, password=None):
#If username is an email address, then try to pull it up
if email_re.search(username):
try:
user = User.objects.get(email=username)
except User.DoesNotExist:
return None
else:
#We have a non-email address username we should try username
try:
user = User.objects.get(username=username)
except User.DoesNotExist:
return None
if user.check_password(password):
return user
|
Comments
Does it works admin app? In my case not :)
#
This is certainly a useful snippet, but it seems a little over complicated. What's wrong with just:
...and then just adding it in front of Django's
ModelBackend?#
The admin login view displays a message "Your email address is not your username" if you attempt to login with an email address and password that do not match (e.g. mistyped the password).
#
adurdin: Alter your template registration/login.html to reflect the change in authentication method.
chris: Just thought I'd let you know, I'm using this and it seems to work very well
Thanks
#
The problem is, the email field in User model is not unique, so you have to do 2 things: monkeypatch your database by addinng necessary constraint to the email field and generate some-kind-of-unique username. Unfortunately, the field is only allowed to keep 30 characters, so you cann't just use munged email or md5 hash for username...
#
More problems with this. Users of our applications keep reporting me various places in django's own admin where "weird" usernames are shown. Sometimes it's really hard to customize admin templates to display something other than default
__str__provided by Django. I'm thinking on dynamic replacing__str__in django.contrib.auth.models.User, maybe using signals?#
The key to having this work with user object functions like 'has_perm()' and the admin interface is that you have to add both the new and default backends to your settings file:
'AUTHENTICATION_BACKENDS = ( 'yourproject.email-auth.EmailBackend', "django.contrib.auth.backends.ModelBackend", ) '
#
One other thing - the max_length for username in contrib.auth.forms.login is 30. It should be increased to the length of the email field, 75 characters by default.
#
Sorry if this is a dumb question, but what would be the correct way to do that?
#
Rich: Probably two ways. Firstly, you can manually alter the database yourself after running syncdb. In fact, you could hook a callback onto the post_syncdb signal to do it automatically every time. Secondly, you could simply edit the django source which is installed to change the field width. Find and edit the User class in django/contrib/auth/models.py.
#
lars: I misread this the first time too. cogat is saying the the FORM field is limited to 30 chars. nothing to do with the db. the database still stores a username (whatever you want, random, truncated version of email etc.) but the EmailBackend checks against the EMAIL in the db. the db does not have to be altered thus.
#
Also see this blog post which does a similar thing, but looks for a separate "email" argument to the "authenticate" method.
#
In Django 1.0 (since beta2) replace
from django.core.validators import email_rewith
from django.forms.fields import email_reFrank, web development Manchester
#