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

如何自动将Django模型的verify_code字段值在1分钟后置空?

Django模型字段1分钟后自动清除的实现方案

方案1:使用Celery异步延迟任务

这是精准定时处理的常用方案,适合需要严格按时清理的场景:

  1. 确保项目已配置好Celery(搭配Redis/RabbitMQ等消息队列)
  2. 定义清除验证码的异步任务:
# tasks.py
from celery import shared_task
from django.utils import timezone
from .models import YourModel  # 替换为你的实际模型类名

@shared_task
def clear_verify_code(instance_id):
    try:
        instance = YourModel.objects.get(id=instance_id)
        # 二次校验时间,避免中途被手动修改
        if instance.verification_timestamp and timezone.now() - instance.verification_timestamp >= timezone.timedelta(minutes=1):
            instance.verify_code = None
            instance.save(update_fields=['verify_code'])
    except YourModel.DoesNotExist:
        pass
  1. 修改模型的save方法,触发延迟任务:
from django.utils import timezone
from .tasks import clear_verify_code

class YourModel(models.Model):
    verify_code = models.IntegerField(blank=True, null=True)
    verification_timestamp = models.DateTimeField(blank=True, null=True)

    def save(self, *args, **kwargs):
        # 判断是否为新设置的验证码
        is_new_code = self.verify_code is not None
        if not self._state.adding:
            original_instance = YourModel.objects.get(id=self.id)
            is_new_code = is_new_code and original_instance.verify_code is None

        if self.verify_code is not None:
            self.verification_timestamp = timezone.now()
            
        super().save(*args, **kwargs)

        # 新设置验证码时,触发1分钟后的清理任务
        if is_new_code:
            # 用实例ID作为任务ID,避免重复任务
            clear_verify_code.apply_async(
                args=[self.id], 
                countdown=60,
                task_id=f"clear_verify_code_{self.id}"
            )

方案2:数据库层面定时清理

不想引入异步服务的话,直接用数据库的定时任务功能处理:

PostgreSQL(依赖pg_cron扩展)

  1. 安装pg_cron扩展:
CREATE EXTENSION pg_cron;
  1. 创建每分钟执行的清理任务:
SELECT cron.schedule('clear_verify_code', '* * * * *', $$
    UPDATE your_app_yourmodel 
    SET verify_code = NULL 
    WHERE verification_timestamp <= NOW() - INTERVAL '1 minute' 
    AND verify_code IS NOT NULL;
$$);

(替换your_app_yourmodel为模型对应的数据库表名)

MySQL(使用事件调度器)

  1. 开启事件调度器:
SET GLOBAL event_scheduler = ON;
  1. 创建定时清理任务:
CREATE EVENT clear_verify_code
ON SCHEDULE EVERY 1 MINUTE
DO
    UPDATE your_app_yourmodel 
    SET verify_code = NULL 
    WHERE verification_timestamp <= NOW() - INTERVAL 1 MINUTE 
    AND verify_code IS NOT NULL;

方案3:请求时惰性清理

小流量项目可以采用这种无依赖方案,仅在实例被访问时检查并清理:

from django.utils import timezone

class YourModel(models.Model):
    verify_code = models.IntegerField(blank=True, null=True)
    verification_timestamp = models.DateTimeField(blank=True, null=True)

    def save(self, *args, **kwargs):
        # 保存前先检查是否需要清理过期验证码
        if self.verify_code is not None and self.verification_timestamp:
            if timezone.now() - self.verification_timestamp >= timezone.timedelta(minutes=1):
                self.verify_code = None
        
        if self.verify_code is not None:
            self.verification_timestamp = timezone.now()
            
        super().save(*args, **kwargs)

    # 或者在获取实例时触发清理
    @classmethod
    def get(cls, *args, **kwargs):
        instance = super().get(*args, **kwargs)
        if instance.verify_code is not None and instance.verification_timestamp:
            if timezone.now() - instance.verification_timestamp >= timezone.timedelta(minutes=1):
                instance.verify_code = None
                instance.save(update_fields=['verify_code'])
        return instance

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.15 18:15:22