Django - how to use built-in login with email instead of username?

I use the built-in login in my application. There are several custom backends or packages for this. but many of them are not what I am looking for.

I made the email unique through django registration at registration. now all i want is to ask for the email address on the login page instead of username.

but if I use some custom backends, such as django email as the username , it fails when used with django-registration.

I do not want to change all authentication servers, I just want to change the login page.

the rest of the site, I'm going to use the username. pe in my user admin page when I write:

welcome {{user}} 

it should display the username. not email.

I need to find a way out of this. I am stuck.

thanks.

+6
source share
2 answers

By default, django.contrib.auth.urls will create a log page from this template.

 (r'^login/$', 'django.contrib.auth.views.login'), 

You need to avoid / override this URL and then create a new view to handle the new login type.

eg.

create a new urls.py login url

 (r'^emaillogin/$', 'email_login_view'), 

create a view to support email login in views.py

 # get default authenticate backend from django.contrib.auth import authenticate, login from django.contrib.auth.models import User # create a function to resolve email to username def get_user(email): try: return User.objects.get(email=email.lower()) except User.DoesNotExist: return None # create a view that authenticate user with email def email_login_view(request): email = request.POST['email'] password = request.POST['password'] username = get_user(email) user = authenticate(username=username, password=password) if user is not None: if user.is_active: login(request, user) # Redirect to a success page. else: # Return a 'disabled account' error message else: # Return an 'invalid login' error message. 

Link: https://docs.djangoproject.com/en/1.4/topics/auth/#django.contrib.auth.login

+9
source

The above approach no longer works on django 1.9. Another approach might be to override the auth form used in the view as:

 class EmailLoginForm(AuthenticationForm): def clean(self): try: self.cleaned_data["username"] = get_user_model().objects.get(email=self.data["username"]) except ObjectDoesNotExist: self.cleaned_data["username"] = "a_username_that_do_not_exists_anywhere_in_the_site" return super(EmailLoginForm, self).clean() 

Then, by defining the login URL, determine how it is:

 url(r'^login/$', django.contrib.auth.views.login, name="login", kwargs={"authentication_form": EmailLoginForm}), url(r'^', include('django.contrib.auth.urls')), 

The best thing about the above approach is that you don’t really touch the authentication process. This is not exactly a “clean” solution, but it is a quick solution. When you determine the login path before enabling auth.urls, it will be evaluated instead of the basic login form

+2
source

All Articles