使用户激活链接过期并从 django 数据库中删除

Bid*_*jhi 4 python django django-views

我有一个用户注册,在单击发送到用户电子邮件地址的令牌链接后,用户的帐户被激活。如果 24 小时内未单击特定链接,我希望使链接过期并从数据库中删除其数据。

我在一处读到,该链接在 48 小时后过期,对吗?

这是我的问题-

如何自动删除24小时内没有点击激活链接的用户?

(到目前为止,我可以通过进入管理面板并检查电子邮件是否已确认来做到这一点)

这是我的激活功能,

def activate(request, uidb64, token):
    try:
       uid = force_text(urlsafe_base64_decode(uidb64))
       user = User.objects.get(pk=uid)
    except (TypeError, ValueError, OverflowError, ObjectDoesNotExist):
       user = None

    if user is not None and account_activation_token.check_token(user, token):
       user.is_active = True
       user.email_confirmed = True
       user.save()
       login(request, user)
       return redirect('home')
    else:
       return render(request, 'user/account_activation_invalid.html')
Run Code Online (Sandbox Code Playgroud)

这是我的 tokens.py 创建令牌,

from django.contrib.auth.tokens import PasswordResetTokenGenerator
from django.utils import six

class AccountActivationTokenGenerator(PasswordResetTokenGenerator):
   def _make_hash_value(self, user, timestamp):
       return (
           six.text_type(user.pk) + 
           six.text_type(timestamp) + 
           six.text_type(user.email_confirmed)
           )

 account_activation_token = AccountActivationTokenGenerator()
Run Code Online (Sandbox Code Playgroud)

我应该改变什么才能实现这一目标?

xyr*_*res 5

令牌的默认过期时间为 3 天(72 小时)。

您不需要将令牌保存在数据库中。令牌已包含创建时间的时间戳。因此,您需要做的就是重写check_token自定义类中的方法并检查时间戳是否为 24 小时前。

大多数代码可以从原始方法中逐字复制。请参阅github 上的源代码

您所要做的就是更改第 49 行

示例代码:

class AccountActivationTokenGenerator(...):
    ...
    def check_token(self, user, token):

        ...
        if (self._num_days(self._today()) - ts) > 1: # 1 day = 24 hours
            return False

        ...
Run Code Online (Sandbox Code Playgroud)

更新:

要在 24 小时后删除未经验证的用户,您可以创建一个每 24 小时运行一次的 cron 作业,检查数据库中是否有未经验证的用户,如果超过 24 小时则将其删除。

这是一个给出了该过程概要的答案:Django - Set Up A Scheduled Job? 。要创建 cron 作业,请参阅操作系统的文档。

添加 cron 作业的另一种方法是使用 django 应用程序,例如django-crondjango-crontab。它们是专门为使此任务变得更容易而创建的,但一般原则与链接答案中描述的相同。

  • @m00ncake 不。 `self._today()` 和 `ts` 都是 `date` 对象。减去它们将返回以“天”为单位的**整数**值。由于令牌中使用的时间戳(“ts”)仅包含日期信息,因此您需要重写令牌生成方法并保存带有小时和分钟信息的时间戳(即“datetime”对象)。 (2认同)