Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

django allauth empty username causes duplicate key in postgress DB

Django 1.8.16 django-allauth 0.27.0 Using postgres as database.

My application does not use usernames, only e-mail addresses as user id. So I use following settings:

ACCOUNT_AUTHENTICATION_METHOD = 'email'
ACCOUNT_USERNAME_REQUIRED = False
ACCOUNT_EMAIL_REQUIRED = True
ACCOUNT_UNIQUE_EMAIL = True
ACCOUNT_EMAIL_VERIFICATION = "mandatory"
ACCOUNT_USER_MODEL_USERNAME_FIELD = None
ACCOUNT_USER_MODEL_EMAIL_FIELD = 'email'

Now when a new user registers, he uses his e-mail address. But when submitting the registration form, I get this error:

IntegrityError at /accounts/signup/
duplicate key value violates unique constraint "auth_user_username_key"
DETAIL:  Key (username)=() already exists.
Request Method: POST
Request URL:    http://swd.localhost:8000/accounts/signup/
Django Version: 1.8.16
Exception Type: IntegrityError
Exception Value:    
duplicate key value violates unique constraint "auth_user_username_key"
DETAIL:  Key (username)=() already exists.

This says exactly what is wrong: The empty username already exists in the auth_user table, field "username", and it seems this is not allowed? But problem is that the username field is ALWAYS empty using above settings. So how can we get around this?

I did not adapt the user model.

like image 707
Davy Avatar asked Feb 04 '26 00:02

Davy


2 Answers

By doing this...

ACCOUNT_USER_MODEL_USERNAME_FIELD = None

... you are telling allauth that your user model has no username field. In your case, that is clearly wrong, as you get a constraint error on that column. So, simply set it to "username" instead of None so that allauth will populate the field correctly.

like image 157
pennersr Avatar answered Feb 05 '26 14:02

pennersr


Solved by writing an allauth account adapter, which fills the user.username field with the email address:

from allauth.account.adapter import DefaultAccountAdapter

class AccountAdapter(DefaultAccountAdapter):
    def save_user(self, request, user, form, commit=False):
        data = form.cleaned_data
        user.username = data['email']  # username not in use
        user.email = data['email']
        if 'password1' in data:
            user.set_password(data['password1'])
        else:
            user.set_unusable_password()

        user.save()
        return user

Didn't change the settings.

Inspired by: How could one disable new account creation with django-allauth, but still allow existing users to sign in?

like image 28
Davy Avatar answered Feb 05 '26 14:02

Davy



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!