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

如何在Django模型中创建触发器删除1天未激活的用户?

在Django中自动删除1天未激活的用户记录

首先,你的User模型缺少创建时间字段,无法判断账号创建时长,所以第一步需要给模型添加created_at字段:

class User(AbstractBaseUser, PermissionsMixin):
    # ... 原有字段 ...
    first_name = models.CharField(max_length=150, blank=True)
    last_name = models.CharField(max_length=150, blank=True)
    is_active = models.BooleanField(default=False)
    # 添加创建时间字段,自动记录用户创建时间
    created_at = models.DateTimeField(auto_now_add=True)
    # ... 原有方法 ...
    
    def __str__(self):
        return self.email
    
    def __getitem__(self,key):
        return self.__dict__[key]

添加后执行迁移命令:python manage.py makemigrations && python manage.py migrate

下面提供几种可行的实现方案,按推荐程度排序:


方案一:使用django-crontab(轻量定时任务,适合小型项目)

这是最简便的方案,利用系统crontab定时执行Django自定义命令。

步骤1:安装依赖

pip install django-crontab

步骤2:配置应用

在项目settings.py的INSTALLED_APPS中添加:

INSTALLED_APPS = [
    # ... 其他应用 ...
    'django_crontab',
]

步骤3:编写清理命令

在你的应用目录下创建management/commands/clean_inactive_users.py(需先创建management和commands文件夹,每个文件夹都要有__init__.py):

from django.core.management.base import BaseCommand
from django.utils import timezone
from datetime import timedelta
from your_app_name.models import User  # 替换为你的应用名

class Command(BaseCommand):
    help = '自动删除超过1天未激活的用户'

    def handle(self, *args, **options):
        # 计算1天前的时间点
        cutoff_time = timezone.now() - timedelta(days=1)
        # 删除符合条件的用户,返回删除数量
        deleted_count, _ = User.objects.filter(
            is_active=False,
            created_at__lt=cutoff_time
        ).delete()
        self.stdout.write(self.style.SUCCESS(f'已成功删除 {deleted_count} 个未激活用户'))

步骤4:配置定时任务

在settings.py末尾添加:

CRONJOBS = [
    # 每天凌晨1点执行一次清理任务(crontab格式:分 时 日 月 周)
    ('0 1 * * *', 'django.core.management.call_command', ['clean_inactive_users']),
]

步骤5:启动定时任务

执行命令添加定时任务到系统crontab:

python manage.py crontab add

可通过以下命令查看/删除定时任务:

python manage.py crontab show
python manage.py crontab remove

方案二:使用Celery + Celery Beat(适合中大型分布式项目)

如果你的项目已在用Celery处理异步任务,推荐此方案,支持分布式部署和灵活的任务调度。

步骤1:编写Celery任务

在应用目录下创建tasks.py:

from celery import shared_task
from django.utils import timezone
from datetime import timedelta
from your_app_name.models import User  # 替换为你的应用名

@shared_task
def clean_inactive_users():
    cutoff_time = timezone.now() - timedelta(days=1)
    deleted_count, _ = User.objects.filter(
        is_active=False,
        created_at__lt=cutoff_time
    ).delete()
    return f'已删除 {deleted_count} 个未激活用户'

步骤2:配置Celery Beat定时任务

在项目settings.py中添加Celery Beat调度配置:

from celery.schedules import crontab

CELERY_BEAT_SCHEDULE = {
    # 每天凌晨1点执行清理任务
    'daily-clean-inactive-users': {
        'task': 'your_app_name.tasks.clean_inactive_users',  # 任务路径
        'schedule': crontab(hour=1, minute=0),
        # 也可按间隔执行:'schedule': timedelta(days=1),
    },
}

步骤3:启动Celery服务

分别启动Celery Worker和Beat调度器:

# 启动Worker处理任务
celery -A your_project_name worker -l info
# 启动Beat调度定时任务
celery -A your_project_name beat -l info

方案三:数据库触发器(不推荐,维护成本高)

直接在数据库层面创建定时触发器,缺点是逻辑脱离Django代码,迁移时易遗漏,且不同数据库语法不兼容。以PostgreSQL为例:

步骤1:安装pg_cron扩展(PostgreSQL定时任务依赖)

CREATE EXTENSION IF NOT EXISTS pg_cron;

步骤2:创建清理函数和定时任务

-- 创建清理未激活用户的函数
CREATE OR REPLACE FUNCTION delete_inactive_users()
RETURNS void AS $$
BEGIN
    DELETE FROM your_app_name_user  -- 替换为你的用户表名(通常是应用名_user)
    WHERE is_active = FALSE
    AND created_at < NOW() - INTERVAL '1 day';
END;
$$ LANGUAGE plpgsql;

-- 设置每天凌晨1点执行清理
SELECT cron.schedule('daily-clean-inactive-users', '0 1 * * *', 'SELECT delete_inactive_users();');

注意事项

  • 关联数据处理:如果有其他模型通过外键关联User,需确保外键字段设置了合理的on_delete属性(如models.CASCADE自动删除关联数据,models.SET_NULL需字段允许为空),避免数据库外键约束错误。
  • 执行频率:可根据业务需求调整定时任务执行频率,比如每6小时执行一次,减少数据库压力。
  • 时区问题:确保Django的TIME_ZONE设置正确,避免时间计算错误。

内容的提问来源于stack exchange,提问作者some nooby questions

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.18 07:05:17