1
votes

I am using django's inbuilt authentication system. Everything seems to be working fine. There are two fields that the user is requested to input at the time of signup: username and email. While logging in they are required to enter username and password.

I'd like to change this behavior so that username field is gone. I want to treat the email as the users username. So while signing in user will be required to put email / password

Is this possible while still using django's inbuilt auth system? I'm on django 1.7

Update

I had the need to add additional fields so I added the following to models.py

from django.db import models from django.contrib.auth.models import User

class UserProfile(models.Model):
    user = models.OneToOneField(User)
    telephone_number = models.CharField(max_length=100)
    website_url = models.CharField(max_length=100)

User.profile = property(lambda u: UserProfile.objects.get_or_create(user=u)[0])
2
This is specifically addressed in the documentation.Daniel Roseman
@DanielRoseman I went through the documentation but I have already made an extra model because I had the Need to add additional fields. See updated section of the questionbirdy

2 Answers

0
votes

The answer is directly in django documentation, in short words you should subclass AbstractBaseUser or AbstractUser (in second case you can't totally remove username field), create your own user manager based on BaseUserManager or UserManager and customize built-in auth forms if you're using it (or any app that you're using is using it).

0
votes

This is not strictly cannon, but to avoid creating a new User class or Auth backend, I tend to let users log in with both username or email.

Anyways you'll want to ensure emails are unique as django does not check this by default.

You'll then have to override the default login view to support this. You can create something along the lines of:

class EmailUsernameLoginView(View):

    def post(self, request):
        next = request.POST.get('next', None)
        username = request.POST.get('username', None)
        password = request.POST.get('password', None)
        error = ''
        if username and password:
            try:
                usr = User.objects.get(email=username)
                username = usr.username
            except User.DoesNotExist:
                pass  # If the user doesn't exist, it's an username
            user = authenticate(username=username, password=password)
            if user is not None:
                if user.is_active:
                    login(request, user)
                    return redirect(next)
                else:
                    error = 'Your account is not active'
            else:
                error = 'The username / email - password comb is wrong'
        else:
            error = 'Please provide a username / email and password' 
        ctx = {'error': error}  # Fill with needed feedback
        return render(request, ctx, 'registration/login.html')

This is just a draft and you should probably include a form to help with validation / cleaning