You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python如何延迟1小时执行任务?激活码过期调度遇错求替代库

问题描述

我正在开发一个需要激活码的用户注册功能,希望激活码1小时后过期,编写了如下代码:

def register(request):
    form = CreateUserForm()
    if request.method == "POST":
        form = CreateUserForm(request.data)
        if form.is_valid():
            email = request.POST.get('email')
            password = request.POST.get('password')
            user = get_user_model()
            user = user_manager.create_user(email=email, password=password)

            # Generate an activation code and store it in the database
            code = generate_activation_code()
            # activation = Activations.objects.create(user=12, code=code)

            # Schedule the activation code for deletion after 1 hour
            schedule_activation_code_deletion(user, code)
            # schedule_activation_code_deletion(user, code)

            # Send the activation code to the user's email address
            subject = "Your verification code"
            message = f"Your verification code is {code}"
            send_email(subject, message, settings.EMAIL_HOST_USER, email)
            return Response('User created.')
    return Response(status=400)

def schedule_activation_code_deletion(user_id, code):
    queue = django_rq.get_queue('default')
    queue.enqueue_in(datetime.timedelta(minutes=1), test)

运行代码时遇到错误:

Error while reading from localhost:5432 : (10054, 'An existing connection was forcibly closed by the remote host', None, 10054, None)

请问有没有其他可用的库可以实现激活码1小时后过期的功能?

替代方案

以下几种方案可以实现你的需求,避开当前的数据库连接问题:

1. 无需定时任务:存储过期时间,验证时判断

这是最简洁的方案,不需要依赖任何任务队列库。创建激活码时直接记录当前时间+1小时的过期时间,用户验证激活码时先检查是否在有效期内:

# 创建激活码时
activation = Activations.objects.create(
    user=user,
    code=code,
    expires_at=datetime.datetime.now() + datetime.timedelta(hours=1)
)

# 验证激活码的逻辑
def verify_code(request):
    code = request.POST.get('code')
    try:
        # 只查询未过期的激活码
        activation = Activations.objects.get(code=code, expires_at__gt=datetime.datetime.now())
        # 激活用户
        activation.user.is_active = True
        activation.user.save()
        # 验证后删除激活码
        activation.delete()
        return Response('激活成功。')
    except Activations.DoesNotExist:
        return Response('激活码无效或已过期。', status=400)

这种方案完全避免了定时任务带来的数据库连接问题,适合大多数场景。

2. 使用Celery实现定时删除

Celery是Python生态中成熟的异步任务队列,支持定时任务。配置完成后,可实现1小时后自动删除激活码:

# 定义异步任务(通常放在tasks.py中)
from celery import shared_task

@shared_task
def delete_activation_code(user_id, code):
    Activations.objects.filter(user=user_id, code=code).delete()

# 在注册函数中调用定时任务
def schedule_activation_code_deletion(user_id, code):
    # countdown参数设置为3600秒(1小时)
    delete_activation_code.apply_async(args=[user_id, code], countdown=3600)

3. 使用Django Q

Django Q是轻量级的Django专属任务队列,配置简单,支持定时任务:

# 安装并配置好Django Q后,编写定时逻辑
from django_q.tasks import async_task

def schedule_activation_code_deletion(user_id, code):
    async_task(
        'your_app.tasks.delete_activation_code',  # 指向任务函数的路径
        user_id,
        code,
        schedule_type='O',  # 一次性任务
        next_run=datetime.datetime.now() + datetime.timedelta(hours=1)
    )

# 对应的删除任务(your_app/tasks.py)
def delete_activation_code(user_id, code):
    Activations.objects.filter(user=user_id, code=code).delete()

4. 使用APScheduler

APScheduler是通用的Python定时任务库,可轻松集成到Django项目中:

# 初始化调度器(可放在项目的apps.py或单独的配置文件中)
from apscheduler.schedulers.background import BackgroundScheduler
import django

django.setup()
scheduler = BackgroundScheduler()
scheduler.start()

# 定义删除任务
def delete_activation_code(user_id, code):
    Activations.objects.filter(user=user_id, code=code).delete()

# 调度任务
def schedule_activation_code_deletion(user_id, code):
    scheduler.add_job(
        delete_activation_code,
        'date',
        run_date=datetime.datetime.now() + datetime.timedelta(hours=1),
        args=[user_id, code]
    )

注意生产环境中需要确保调度器随Django进程持续运行,可配合supervisor等进程管理工具。

内容的提问来源于stack exchange,提问作者Orl13

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.22 11:47:54