在 Django Rest Framework 中处理 JWT 身份验证和软删除用户
Handling JWT Authentication and Soft Deleted Users in Django Rest Framework
我正在尝试让用户名在用户删除帐户后可用。默认情况下,用户名是唯一的,这意味着即使帐户被软删除,用户名也将不可用。
默认情况下,这是开箱即用的 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
作为身份验证过程的一部分。有什么办法可以做到吗?
我猜当从 UserModel 调用 authenticate
时会引发错误。查看此方法的 source code, the method calls get_by_natural_key
from the user manager. Examining the 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()
我正在尝试让用户名在用户删除帐户后可用。默认情况下,用户名是唯一的,这意味着即使帐户被软删除,用户名也将不可用。
默认情况下,这是开箱即用的 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
作为身份验证过程的一部分。有什么办法可以做到吗?
我猜当从 UserModel 调用 authenticate
时会引发错误。查看此方法的 source code, the method calls get_by_natural_key
from the user manager. Examining the 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()