13

I have a sign up form which asks only for email and password. When a user signs up, django-allauth creates a username for that user by striping the "@email" suffix form the user's email address.

So for example, if a user signs up with "[email protected]" his username will be "some-user" and if another user signs up with "[email protected]" then his username will be "some-userr"

But what I want is the username and email of the users to have the same value.

So how can I configure django-allauth to set the usernames as the users emails without striping their suffixes?

And if possible, how can I do that without creating a custom user.

In my settings.py:

######################### # AllAuth Configuration # ######################### ACCOUNT_AUTHENTICATION_METHOD = 'email' ACCOUNT_EMAIL_REQUIRED = True ACCOUNT_UNIQUE_EMAIL = True ACCOUNT_USERNAME_REQUIRED = False ACCOUNT_EMAIL_VERIFICATION = 'mandatory' ACCOUNT_PASSWORD_MIN_LENGTH = 8 
1
  • Why would you need the username to be same as the email. You can allow your user to sign up with the email address anyway. Commented Dec 8, 2014 at 3:22

3 Answers 3

27

I do exactly what you want to do with a signal on User pre_save.

Your settings look ok, so if you add the following code in somewhere like for example core.models.py it will work as you need:

@receiver(pre_save, sender=User) def update_username_from_email(sender, instance, **kwargs): user_email = instance.email username = user_email[:30] n = 1 while User.objects.exclude(pk=instance.pk).filter(username=username).exists(): n += 1 username = user_email[:(29 - len(str(n)))] + '-' + str(n) instance.username = username 

The reason I do it with a signal is that I want that every time User is saved, the username is updated. You could check if the e-mail has changed update the username only in that case.

Then I limit the username to the first 30 characters of email (default max lenght of username is 30 chars):

username = user_email[:30] 

You could also change the max lenght of username, but in my case I prefered to use the default lenght.

Since I make this, it could happen that there are repeated usernames. To avoid repeated usernames, in case that the resulting username after limiting it to 30 characters already exists, I put -2, -3... at the end to make the username unique:

n = 1 while User.objects.exclude(pk=instance.pk).filter(username=username).exists(): n += 1 username = user_email[:(29 - len(str(n)))] + '-' + str(n) instance.username = username 

I hope this solution helps you!

Sign up to request clarification or add additional context in comments.

3 Comments

Thank you! Great answer! This is exactly what I want. Sorry that I can't upvote you. I don't have enough reputation yet. When I have I will vote.
Good to hear that it helped! :)
The max length of username is now 150: github.com/django/django/blob/… P.S. Ten years later, this solution still works perfectly :)
9

profiles.models.py (custom user model)

from allauth.socialaccount.adapter import DefaultSocialAccountAdapter class CustomSocialAccountAdapter(DefaultSocialAccountAdapter): def populate_user(self, request, sociallogin, data): user = super().populate_user(request, sociallogin, data) user.username = user.email return user 

settings.py

SOCIALACCOUNT_ADAPTER = "profiles.models.CustomSocialAccountAdapter" 

1 Comment

+1 This. Built-in method to do it. Source.
0

ACCOUNT_AUTHENTICATION_METHOD (default: "username", alternatives: "email" or "username_email") Specifies the login method to use – whether the user logs in by entering their username, email address, or either one of both. Setting this to "email" requires ACCOUNT_EMAIL_REQUIRED=True

Full configuration here

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.