windows环境下python3.7+Django3.2+django_apscheduler0.6实现定时任务
最近在做一个Django项目的时候,遇到了这样一个问题:我需要每隔30min让Django自动执行一个函数,并通过这个函数向数据库中写入一些数据,直接通过页面自动刷新来调用视图函数去实现,会给使用者带来极差的体验,所以就想到了能不能用一步线程的方式实现,比如Django-celery等,但遗憾的是Windows并不支持Django-celery,而我的项目部署在win平台上,所以使用Django3.2+django_apscheduler0.6来实现每隔30min定时向数据库写入一点东西的需求。
网上很多人将定时计划任务写到视图函数所在的脚本中,在此不建议,那么干会给项目维护带来困难。
1.django_apscheduler介绍
这是一个 Django 应用程序,它在 APScheduler 周围添加了一个轻量级包装器。它允许使用 Django 的 ORM 在数据库中存储持久作业。django_apscheduler只使用很少的依赖项和额外配置,就能将调度功能添加到Django应用程序中,而使用者需要注意的仅仅是确保同一时间点上只有一个调度程序在运行。
2.django_apscheduler提供的额外功能
- 调度器管理库
可以在Django后台管理看到你所定义的调度器及执行情况。包括当前所有的调度器和调度器的执行情况都可以看到,很详细。
3.django_apscheduler使用
-
1.安装django-apscheduler
pip install django-apscheduler
-
2.在Django配置文件中注册
注册django_apscheduler到INSTALLED_APPS中INSTALLED_APPS = ( # ... "django_apscheduler", )
-
3.改变Django调度器后台管理界面中显示的时间格式
APSCHEDULER_DATETIME_FORMAT = "N j, Y, f:s a"
-
4.设置超时时间
# 超时时间 秒 APSCHEDULER_RUN_NOW_TIMEOUT = 25
-
5.执行迁移生成调度器管理表
python manage.py migrate
-
6 .在任意已注册的app下创建目录
management /commands
然后在该目录下,新建runapscheduler.py
,注意该文件名不能以_开头,然后使用下面的代码:import logging from django.conf import settings from apscheduler.schedulers.blocking import BlockingScheduler from apscheduler.triggers.cron import CronTrigger from django.core.management.base import BaseCommand from django_apscheduler.jobstores import DjangoJobStore from django_apscheduler.models import DjangoJobExecution from django_apscheduler import util logger = logging.getLogger(__name__) def my_job(): # 此处写你要执行的定时任务 print("hello Django") pass # 设置保留历史作业执行记录的最长时间,防止数据库被填满 @util.close_old_connections def delete_old_job_executions(max_age=604_800): """ :param max_age: 历史执行记录最长保留7天 """ DjangoJobExecution.objects.delete_old_job_executions(max_age) # 自定义的Django命令,就是runapscheduler.py的文件名 class Command(BaseCommand): help = "Runs APScheduler." def handle(self, *args, **options): scheduler = BlockingScheduler(timezone=settings.TIME_ZONE) scheduler.add_jobstore(DjangoJobStore(), "default") scheduler.add_job( my_job, trigger=CronTrigger(second="*/10"), # 每隔十秒执行一次,时间可以按实际需求设定 id="my_job", # 你要执行的函数 max_instances=1, replace_existing=True, ) logger.info("Added job 'my_job'.") scheduler.add_job( delete_old_job_executions, trigger=CronTrigger( day_of_week="mon", hour="00", minute="00" ), # Midnight on Monday, before start of the next work week. id="delete_old_job_executions", max_instances=1, replace_existing=True, ) logger.info( "Added weekly job: 'delete_old_job_executions'." ) try: logger.info("Starting scheduler...") scheduler.start() except KeyboardInterrupt: logger.info("Stopping scheduler...") scheduler.shutdown() logger.info("Scheduler shut down successfully!")
-
7 . 启动定时器
在启动Django项目之前,使用命令:python manage.py runapscheduler
启动调度器,然后Django就会按照你设定的时间自动定时执行。runapscheduler就是在management /commands目录下定义的py文件的文件名。
最后也是达到了我想要的效果,我使用的Django是3.2,django_apscheduler是0.6。
更多高级用法。