【问题标题】:Handling JWT Authentication and Soft Deleted Users in Django Rest Framework在 Django Rest Framework 中处理 JWT 身份验证和软删除用户
【发布时间】:2021-04-11 05:07:24
【问题描述】:

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

默认情况下,这是 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 是否作为身份验证过程的一部分。有没有办法做到这一点?

【问题讨论】:

    标签: django django-rest-framework soft-delete django-rest-framework-simplejwt


    【解决方案1】:

    我猜当从 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()
    

    【讨论】:

    • 为我工作。谢谢。但是,is_active 需要引用,因为它不是变量。
    猜你喜欢
    • 2019-01-01
    • 2020-04-10
    • 2015-06-01
    • 2013-05-03
    • 2019-11-20
    • 2017-12-23
    • 2019-07-29
    • 2021-04-04
    • 1970-01-01
    相关资源
    最近更新 更多