django allauth空用户名导致postgress DB中的重复密钥

时间:2017-02-10 13:24:14

标签: django django-allauth

Django 1.8.16 django-allauth 0.27.0 使用postgres作为数据库。

我的应用程序不使用用户名,只使用电子邮件地址作为用户ID。 所以我使用以下设置:

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'

现在,当新用户注册时,他会使用他的电子邮件地址。 但是在提交注册表时,我收到了这个错误:

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.

这确切地说错了:auth_user表中存在空用户名,字段"用户名",似乎不允许这样做? 但问题是使用上述设置,用户名字段始终为空。 那么我们怎样才能解决这个问题?

我没有调整用户模型。

3 个答案:

答案 0 :(得分:3)

这样做......

ACCOUNT_USER_MODEL_USERNAME_FIELD = None

...您告诉allauth您的用户模型没有username字段。在您的情况下,这显然是错误的,因为您在该列上遇到约束错误。因此,只需将其设置为"username"而不是None,以便allauth正确填充字段。

答案 1 :(得分:1)

通过编写allauth帐户适配器解决,该适配器使用电子邮件地址填写user.username字段:

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

没有更改设置。

灵感来自: How could one disable new account creation with django-allauth, but still allow existing users to sign in?

答案 2 :(得分:0)

这里的错误是由于默认 Django 用户模型中的用户名字段造成的。 您需要从 User 模型中删除 username 字段。您可以做的一件事是覆盖用户模型。您可以在您的应用程序中创建一个新的自定义 User 模型,并将其设置为 settings.py 中的默认 User 模型

在您的应用的 models.py 中

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

class User(AbstractUser):
    # Creating an email login.
    username = None
    USERNAME_FIELD = 'email'

创建用户模型后,在 settings.py 中将其配置为默认值

AUTH_USER_MODEL = 'your_app.User'

# Specify the username field of your model as well for all auth.
ACCOUNT_USER_MODEL_USERNAME_FIELD = 'email'

这应该可以完成您的工作。