0

一旦用户删除他们的帐户,我正在尝试使用户名可用。默认情况下,用户名是唯一的,这意味着即使在帐户被软删除后,用户名也将不可用。

默认情况下,这是 django 开箱即用的设置。

class CustomUser(AbstractUser):
    username = models.CharField(
        _('username'),
        max_length=150,
        unique=True,
        help_text=_('Required. 150 characters or fewer. Letters, digits and @/./+/-/_ only.'),
        validators=[UnicodeUsernameValidator()],
        error_messages={
            'unique': _("A user with that username already exists."),
        },
    )
    is_active = models.BooleanField(
        _('active'),
        default=True,
        help_text=_(
            'Designates whether this user should be treated as active. '
            'Unselect this instead of deleting accounts.'
        ),
    )

is_active此处用于将模型标记为已删除。

为了能够利用UniqueConstraint并添加条件,我必须删除用户名的唯一性。

class CustomUser(AbstractUser):
    username = models.CharField(
        _('username'),
        max_length=150,
        unique=False,
        help_text=_('Required. 150 characters or fewer. Letters, digits and @/./+/-/_ only.'),
        validators=[UnicodeUsernameValidator()],
        error_messages={
            'unique': _("A user with that username already exists."),
        },
    )
    is_active = models.BooleanField(
        _('active'),
        default=True,
        help_text=_(
            'Designates whether this user should be treated as active. '
            'Unselect this instead of deleting accounts.'
        ),
    )

    class Meta:
        constraints = [
            models.UniqueConstraint(
                fields=['username'],
                name='active_username_constraint',
                condition=models.Q(is_active=True)
            )
        ]

这适用于注册。用户删除帐户后,用户名可以在注册期间重新使用。但是,当用户登录时,会引发以下错误。

MultipleObjectsReturned at /api/vdev/login/
get() returned more than one CustomUser -- it returned 2!

我正在尝试找出一种方法来检查用户是否is_active作为身份验证过程的一部分。有没有办法做到这一点?

4

1 回答 1

2

我猜authenticate从 UserModel 调用时会引发错误。查看源代码get_by_natural_key,从用户管理器调用方法。检查此方法的源代码向我们展示了我们需要在哪里进行更改。

因此,您可能需要做的是创建一个自定义用户管理器,继承BaseUserManager并覆盖get_by_natural_key.

class MyUserManager(BaseUserManager):
    ...
    def get_by_natural_key(self, username):
        return self.get(**{self.model.USERNAME_FIELD: username, "is_active": True})

然后在您的自定义用户模型中,将您的管理器设置为此自定义用户管理器:

class CustomUser(AbstractUser):
    ...
    objects = MyUserManager()
于 2021-01-05T13:16:39.497 回答