问题描述
我正在尝试在用户删除其帐户后提供用户名。默认情况下,用户名是唯一的,这意味着即使帐户被软删除后用户名也不可用。
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.'
),)
为了能够利用 UniqueConstraint
并添加条件,我必须放弃用户名的唯一性。
class CustomUser(AbstractUser):
username = models.CharField(
_('username'),unique=False,)
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
是否作为身份验证过程的一部分。有没有办法做到这一点?
解决方法
我猜当从 UserModel 调用 authenticate
时会引发错误。查看 source code,该方法从用户管理器调用 get_by_natural_key
。检查此方法的 source code 会告诉我们需要进行更改的位置。
因此,您可能需要做的是创建一个自定义用户管理器,继承自 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()