避免在 django allauth 的自定义用户模型中创建用户名字段

Cha*_*ase 3 python django django-allauth

我正在使用带有 allauth 的自定义用户模型,并且需要省略用户名字段。我已经看过文档和一大堆关于使用的 stackoverflow 答案ACCOUNT_USER_MODEL_USERNAME_FIELD = None,但所有这些仍然导致我的数据库有一个用户名字段。

现在,由于数据库仍然有一个username设置了唯一约束的字段,并且allauth 不会在上述设置设置为 的字段中放置用户名,这导致我在第一个用户创建后None面临。IntegrityError我知道我可以通过设置上述设置来解决这个问题,'username'但我很好奇,我如何不创建用户名,因为我从不使用它。

我的型号:

class CustomUser(AbstractUser):
    # Custom user model for django-allauth
    first_name = None
    last_name = None

    def delete(self):
        # Custom delete - make sure user storage is also purged
        # Purge the user storage
        purge_userstore(self.email)
        # Call the original delete method to take care of everything else
        super(CustomUser, self).delete()

Run Code Online (Sandbox Code Playgroud)

除了覆盖该函数之外,它实际上并没有做太多事情delete。此覆盖与本主题无关,但我将其包含在内只是为了完整性。它还设置first_namelast_nameto None,它可以完美地工作并按预期从数据库中删除这些字段。我尝试过设置userNone但没有任何作用。我也尝试过设置,username但这None会引发FieldNotFound错误ACCOUNT_USER_MODEL_USERNAME_FIELD = None

我的设置(相关位):

AUTHENTICATION_BACKENDS = (
    "django.contrib.auth.backends.ModelBackend",
    "allauth.account.auth_backends.AuthenticationBackend",
)
AUTH_USER_MODEL = 'custom_account.CustomUser'
ACCOUNT_USER_MODEL_USERNAME_FIELD = None
ACCOUNT_USERNAME_REQUIRED = False
ACCOUNT_EMAIL_REQUIRED = True
ACCOUNT_UNIQUE_EMAIL = True
ACCOUNT_AUTHENTICATION_METHOD = 'email'
Run Code Online (Sandbox Code Playgroud)

我的迁移文件:

migrations.CreateModel(
            name='CustomUser',
            fields=[
                ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
                ('password', models.CharField(max_length=128, verbose_name='password')),
                ('last_login', models.DateTimeField(blank=True, null=True, verbose_name='last login')),
                ('is_superuser', models.BooleanField(default=False, help_text='Designates that this user has all permissions without explicitly assigning them.', verbose_name='superuser status')),
                ('username', models.CharField(error_messages={'unique': 'A user with that username already exists.'}, help_text='Required. 150 characters or fewer. Letters, digits and @/./+/-/_ only.', max_length=150, unique=True, validators=[django.contrib.auth.validators.UnicodeUsernameValidator()], verbose_name='username')),
                ('email', models.EmailField(blank=True, max_length=254, verbose_name='email address')),
                ('is_staff', models.BooleanField(default=False, help_text='Designates whether the user can log into this admin site.', verbose_name='staff status')),
                ('is_active', models.BooleanField(default=True, help_text='Designates whether this user should be treated as active. Unselect this instead of deleting accounts.', verbose_name='active')),
                ('date_joined', models.DateTimeField(default=django.utils.timezone.now, verbose_name='date joined')),
                ('groups', models.ManyToManyField(blank=True, help_text='The groups this user belongs to. A user will get all permissions granted to each of their groups.', related_name='user_set', related_query_name='user', to='auth.Group', verbose_name='groups')),
                ('user_permissions', models.ManyToManyField(blank=True, help_text='Specific permissions for this user.', related_name='user_set', related_query_name='user', to='auth.Permission', verbose_name='user permissions')),
            ],
....
Run Code Online (Sandbox Code Playgroud)

这一代移民让我困惑不已。为什么田野username还在?即使我已经明确设置,为什么它被设置为唯一的唯一约束ACCOUNT_UNIQUE_EMAIL = True

注意:此迁移文件是从头开始生成的,这是根据我提供的代码生成的第一个也是唯一一个迁移文件。

起初我以为我的设置根本没有被读取。但我检查了django.conf.settingsallauth.account.app_settings在 shell 中)这些更改,它们都已更新。这里发生了什么?

注意:在我搜索过的许多 stackoverflow 问题中,这个问题似乎特别完美地解释了我的问题。对于一个小问题,allauth 的创建者本人建议使用ACCOUNT_USER_MODEL_USERNAME_FIELD = "username"作为有问题的模型的答案是“明确使用该username字段”。但答案并没有解释当你根本不想使用该username字段时该怎么做。

Cha*_*ase 7

看起来摆脱该username字段的唯一方法是覆盖 的AbstractUser用户名字段和/或从头开始使用完全自定义的模型。认为覆盖AbstractBaseUser也应该起作用,尽管AbstractBaseUser提供的功能较少。

class CustomUser(AbstractUser):
    # Custom user model for django-allauth
    # Remove unnecessary fields
    username = None
    first_name = None
    last_name = None
    # Set the email field to unique
    email = models.EmailField(_('email address'), unique=True)
    # Get rid of all references to the username field
    EMAIL_FIELD = 'email'
    USERNAME_FIELD = 'email'
    REQUIRED_FIELDS = []
Run Code Online (Sandbox Code Playgroud)

此模型将删除该username字段并使该email字段唯一,并将所有对 的引用更改USERNAME_FIELD'email'。请注意,该内容REQUIRED_FIELDS应该为空,因为USERNAME_FIELD不能在那里。使用 allauth 时,这不是问题,电子邮件和密码要求无论如何都是由 allauth 管理的。

我在问题中提到的设置应该保持不变,具体来说-

ACCOUNT_USER_MODEL_USERNAME_FIELD = None
ACCOUNT_USERNAME_REQUIRED = False
ACCOUNT_EMAIL_REQUIRED = True
Run Code Online (Sandbox Code Playgroud)