自学Python第二十二天- Django框架(六) django的实用插件:cron、APScheduler

django-crontab 和 django-cron

有时候需要django在后台不断的执行一个任务,简单的可以通过中间件来实现,但是中间件是根据请求触发的。如果需要定时执行任务,则需要使用到一些插件。

django-crontab 和 django-cron 是常用的用于处理定时任务的插件库,两者区别在于:

  • django-cron 完全运行在 django 服务器内部的库,它通过定期检查当前时间与定义的任务计划是否匹配来执行任务。它不依赖于系统级的cron守护进程,而是基于 django 自身的请求周期触发任务检查
  • django-crontab 是利用操作系统的 cron 守护进程来调度任务。用户在 django 项目中定义好任务后, django-crontab 会将这些任务写入到系统的 crontab 文件中。当 cron 守护进程执行任务时,实际上会调用 django 管理命令或 url 来执行特定的操作。

django-crontab

使用 django-crontab 需要以下步骤:

  1. 安装 django-crontab 模块
  2. settings.py 中注册应用
  3. 创建定时执行的任务(可以是自定义的函数或自定义的命令)
  4. settings.py 中配置执行任务
  5. 执行任务

需要注意的是 django-crontab 只能运行在 linux 环境中,且需要使用到 root 权限。另外需要启动 cron 服务

# 查看 cron 服务状态
service cron status
# 开启 cron 服务
service cron start
# 查看定时任务
crontab -l
# 添加定时任务 
crontab -e

安装 django-crontab

pip install django-crontab

注册应用

settings.py 中注册 django-crontab 应用

INSTALLED_APPS = [...'django_crontab',
]

创建任务

创建定时执行的任务

创建定时执行函数

在任意 app 下均可创建定时执行函数

# app1/task.pydef scheduleTask():		# 定时执行函数from time import strftime, localtimeprint(strftime("%Y-%m-%d %H:%M:%S", localtime()), end='')print("执行了scheduleTask函数")def scheduleTaskWithPara(in_str):		# 带参数的定时执行函数import datetimenow_time = datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')print(f"在 {now_time} 执行了定时函数,输入信息{in_str}")
创建定时执行命令

在任意 app 下创建 management 模块(含有 __init__.py 文件),并在此模块下创建 commands 模块。在 commands 模块下创建具体的执行脚本文件。例如:

# app1/management/commands/mycommand1.pyfrom django.core.management.base import BaseCommand, CommandError
from time import strftime, localtimeclass Command(BaseCommand):help = '这是第一个command测试指令'# 为handle中添加参数解析,def add_arguments(self, parser):parser.add_argument('-p', # 设置参数的时候  前边携带'--param',action='store',dest='param',  # 自定义传入的参数键名ssdefault='close',  # 默认的键值help='name of author.',)def handle(self, *args, **options):# print("mycommand1----开始")'''添加你需要功能,(访问数据库,判断有效性等等)...'''# 例如try:if options['param']:print(strftime("%Y-%m-%d %H:%M:%S", localtime()), end='')print(": mycommand1传入的参数为", options['param'])except Exception as e:print("12",e)print(CommandError("1111111111111111111111111"))# print("mycommand1----结束")
# app1/management/commands/mycommand2.pyfrom django.core.management.base import BaseCommand
from time import strftime, localtimeclass Command(BaseCommand):help = '这是第二个command测试指令'# 为handle中添加参数解析,def add_arguments(self, parser):parser.add_argument('-p', # 设置参数的时候  前边携带'--param',action='store',dest='param',  # 自定义传入的参数键名ssdefault='close',  # 默认的键值help='name of author.',)def handle(self, *args, **options):# print("mycommand2----开始")'''添加你需要功能,(访问数据库,判断有效性等等)...'''# 例如if options['param']:print(strftime("%Y-%m-%d %H:%M:%S", localtime()), end='')print("mycommand2传入的参数为", options['param'])# print("mycommand2----结束")

配置任务

将创建好的定时执行任务配置到 settings.py 中去,以方便执行

配置定时执行函数

在 CRONJOBS 列表中添加一个元组,第一个元素是执行间隔时间,第二个元素是执行任务函数。如没有参数第三个元素是输出处理,如有参数第三、四元素分别为传参,第五参数是输出处理。例如:

CRONJOBS = [# 每1分钟执行scheduleTask函数,并将执行中的返回的内容全部打印到crontab.log文件中('*/1 * * * *', 'app1.tasks.scheduleTask', '>> /tmp/crontab.log'),('*/1 * * * *', 'app1.tasks.scheduleTaskWithPara', ['James'], {}, '>> /tmp/crontab.log'),
]
配置定时执行命令

类似于定时执行函数,将定时执行命令添加到 CRONJOBS 列表中去。区别在于元组的元素定义不同

CRONJOBS = [# 每1分钟执行django的自定义命令,并将执行中的返回的内容全部打印到crontab.log文件中('*/1 * * * *', 'django.core.management.call_command', ['mycommand1'], {"param": "mycommand1_test"}, '>>/home/wangzhipeng/myproject/crontab.log'),('*/1 * * * *', 'django.core.management.call_command', ['mycommand2'], {"param": "mycommand2_test"}, '>>/home/wangzhipeng/myproject/crontab.log')
]
  • 元素1:定时 例如*/1 * * * * 表示每隔1分钟执行
  • 元素2:方法的python模块路径,如果执行django-admin命令,则写django.core.management.call_command
  • 元素3:方法的位置参数列表(默认值:[]),如果执行django-admin命令,则填写所需执行的命令
  • 元素4:方法的关键字参数的dict(默认值:{})
  • 元素5:执行log存放位置(即重定向到文件,默认:‘’)

配置完成后可以进行测试:

python manage.py mycommand1 -p 123
# 2019-05-10 15:10:59: mycommand1传入的参数为 123
关于 linux 的 crontab 时间语法

crontab 的时间语法由五部分组成,通常为五个 *,每一位表示的意思分别为:分钟、小时、日、月、星期。
可使用的字符和其意义为:

字符含义
*代表所有取值范围的数字
/代表“每”的意思,例如 */5 表示5个单位
-代表从某个数字到某个数字
,分隔离散的数字

例如:

示例含义
0 */2 * * *每2个小时
0 23-7,9 * * *23点到7点,或9点
0 11 4 * 1-3每月4号或周一到三的11点
0 4 1 1 *1月1日4点
0 6 * * *每天6点
0 */2 * * *每2小时

执行任务

添加并开启定时任务:

python manage.py crontab add

查看执行中的定时任务

python manage.py crontab show

删除(停止)定时任务

python manage.py crontab remove 

django-cron

django-cron 因为完全基于 django,使得使用简单。但是也是这个原因,要想使定时任务生效,django服务必须一直处于运行状态。

另外 django-cron django-cron会依赖于HTTP请求来触发其内部的任务检查逻辑(通过中间件实现)。这意味着只有当有用户访问网站或通过其他方式触发HTTP请求时,cron任务才可能被执行。

需注意的是,dnango-cron 也只能在 linux 系统上运行。

(django-cron英文文档)[https://django-cron.readthedocs.io/en/latest/]

使用 django-cron 需要以下步骤:

  1. 安装 django-cron 模块
  2. settings.py 中注册应用
  3. 进行迁移,创建 django_cron 应用所需资源
  4. 创建定时执行的任务类
  5. settings.py 中配置执行任务

安装 django-cron

pip install django-cron

注册应用

settings.py 中注册应用:

INSTALLED_APPS = [# ..."django_cron",
]

创建 django_cron 资源

python manage.py migrate django_cron

创建任务类

和 django-crontab 不同的是, django-cron 的定时任务是一个集成自 django_cron.CronJobBase 的类

# app1/cron.py
from django_cron import CronJobBase, Schedule
from django.core.management import call_commandclass MyCronJob(CronJobBase):RUN_EVERY_MINS = 30  # 每30分钟运行一次schedule = Schedule(run_every_mins=RUN_EVERY_MINS)		# 添加任务执行周期code = 'yourapp.my_cron_job'  # 唯一标识符def do(self):# 执行的命令或函数call_command('your_management_command')  # 如果是管理命令# 或执行任意Python代码my_function()

如果需要在指定时间执行任务,而不是按周期执行,则使用schedule = Schedule(run_at_times=['11:30', '14:00', '23:15']),注意必须使用24小时制。按照周期执行和执行时间执行可以一起使用。schedule = Schedule(run_every_mins=RUN_EVERY_MINS, run_at_times=RUN_AT_TIMES)

配置任务

需要在 settings.py 中的 CRON_CLASSES 列表中注册此任务

CRON_CLASSES = ["app1.cron.MyCronJob",
]

执行任务

在 django-cron 中,定时任务是在 django 应用运行时触发执行的。如果需要立即运行所有的 cron 任务,例如部署新代码后或进行测试时,可以手动执行任务。

python manage.py runcrons

也可以单独指定手动执行具体的哪个任务类

python manage.py runcrons "app1.cron.MyCronJob" "app1.cron.OtherCronJob"

如果需要静默执行,即不输出相关信息,可以添加参数 --silent
如果需要强制执行,可以添加参数 --force
如果需要查看有哪些任务可以执行,而并不真的运行这些任务,可以添加参数 --dry-run

django-apscheduler

cron 是基于 unix_like 系统的,windows 下使用 APScheduler。APscheduler全称Advanced Python Scheduler,它是一个轻量级的 Python 定时任务调度框架。APScheduler 支持三种调度任务:固定时间间隔,固定时间点(日期),Linux 下的 Crontab 命令。同时,它还支持异步执行、后台执行调度任务。

django-apscheduler 是 APScheduler 的django定制封装插件版,专为 django 设计。它的使用流程为:

  1. 安装
  2. 注册应用
  3. 配置
  4. 执行迁移
  5. 创建任务
  6. 初始化调度器,并添加任务
  7. 启动任务

apscheduler英文文档
参考文档:定时任务框架APScheduler学习

安装

pip install django-apscheduler

注册应用

settings.py 中注册 app

INSTALLED_APPS = [# ...'django_apscheduler',
]

执行迁移

python manage.py migrate

APScheduler 会在数据库中创建2张表

  • django_apscheduler_djangojob : 用于存储定时任务
  • django_apscheduler_djangojobexecution : 用于存储每次的执行记录、时长和执行结果等。

创建任务

apscheduler 的任务就是普通的函数,可以将需要执行的内容写在函数内部,然后使用调度器添加任务即可

def scheduler_task():pass		# 这里是任务需要执行的内容

创建调度器,添加任务

django_apscheduler 是基于 APScheduler 使用的,安装了 django_apscheduler 会自动安装 APScheduler。调度器需要使用 apscheduler.schedulers.backgroud.BackgroundSchedulerapscheduler.schedulers.blocking.BlockingScheduler 两个类中的一个来实例化调度器。两者区别在于 BackgroundScheduler 会在后台执行,而 BlockingScheduler 会在主线程执行,进而阻塞主线程。因此常用 BackgroundScheduler 来创建调度器。

from apscheduler.schedulers.background import BackgroundScheduler
from django_apscheduler.jobstores import DjangoJobStore, register_job, register_eventsdef init_scheduler():scheduler = BackgroundScheduler()			# 创建调度器try:scheduler.add_jobstore(DjangoJobStore(), 'default')		# 添加调度器作业存储# 添加定时任务,每天0点,30分执行一次,任务id为test。scheduler.add_job(scheduler_test, 'cron', hour=0, minute=30, id='test', replace_existing=True)	# 添加定时任务,间隔3秒执行一次scheduler.add_job(scheduler_jog, 'interval', seconds=3, id='3_second_job')# 用装饰器的方式添加任务@regist_job(scheduler, "interval", seconds=10, replace_existing=True, id="task_per_10s")def task_per_10_seconds():print('间隔10秒执行任务')# 注册处理事件register_events(scheduler)# 调度器开始工作,计时器开始计时scheduler.start()	except Exception as e:print(e)# 报错则调度器终止运行,否则会跳过错误任务继续执行scheduler.shutdown()

scheduler.add_job(func, trigger=None, args=None, kwargs=None, id=None, name=None, misfire_grace_time=undefined, coalesce=undefined, max_instances=undefined, next_run_time=undefined, jobstore='default', executor='default', replace_existing=False, **trigger_args) 方法可以将任务添加至调度器,其参数有:

  • func 必须参数,需要执行的任务函数(或可调用对象)
  • trigger 必须参数,定时器类型,可以是触发器实例或触发器字符串
  • argskwargs:传递给任务函数的参数列表和关键字参数字典。主要用于trigger使用字符串时,传递具体的定时时间。
  • idname:分别用于唯一标识和命名一个任务。如果未提供,将自动生成。
  • misfire_grace_time:任务错过执行的时间窗口,在这个时间段内,即使错过了计划执行时间点,也会被执行。
  • coalesce:布尔值,表示当任务被错过多次后是否合并执行(只执行一次而不是多次)。
  • max_instances:同一时间内允许的最大并发执行实例数。
  • next_run_time:手动指定下一次运行时间(通常由调度器自动计算)。
  • jobstore:指定存储此任务的作业存储。通常配置为 ‘default’ 或 DjangoJobStore 的实例,且在 add_job 之前使用 add_jobstore 方法配置。
  • executor:执行器实例,负责实际执行作业。默认使用已配置好的执行器。
  • replace_existing:是否替换同名或同ID的任务,解决第二次调度任务时因为第一次任务未完成而报错的问题

APScheduler 支持的定时器主要有:

定时器说明
cron基于 unix_like 系统的 cron 定时任务
interval重复定时器
date固定时间定时器

scheduler.add_job() 添加定时器时,可以在第二个参数以字符串形式指定定时器类型,然后使用关键字传参的方式传入具体时间,也可以使用apscheduler.triggers.cron.CronTriggerapscheduler.triggers.interval.IntervalTriggerapscheduler.triggers.date.DateTrigger 创建定时器对象实例传入第二个参数(或用关键字传参传给trigger)。

cron 定时器:
在这里插入图片描述
interval 定时器:
在这里插入图片描述
date 定时器
在这里插入图片描述

启动任务

在 django 中执行调度器即可开始定时任务,网上很多推荐添加到 urls.py 中执行。如果定时器中需要涉及 django 资源,例如需要使用 app 的 models 来操作数据库,则需要相应资源加载完成。这里推荐写到 app 的 apps.py 中,在设置类的 ready() 方法中,可以在 app 准备完成时执行。

# app1/apps.py
from django.apps import AppConfigclass App1Config(AppConfig):default_auto_field = 'django.db.models.BigAutoField'name = 'app1'def ready(self):super().ready()run_once = os.environ.get('CMDLINE_DJANGO_RUNNER_RUN_ONCE')if run_once is not None:returnos.environ['CMDLINE_DJANGO_RUNNER_RUN_ONCE'] = 'True'# 在这里执行 APScheduler 定时任务

需要注意的是,启动任务前必须完成迁移工作,否则 django_apscheduler 会因数据库中没有创建2张表而报错。

另外 django 默认 runserver 时会创建一个守护进程来监控代码有没有改变以计时重启服务,这在调试时是非常方便的,但是定时任务也会重复执行。所以启用执行任务时需使用 python manage.py runserver --noreload ,或在环境变量(不能在django服务中,因为django进程间数据隔离)添加一个状态量,作为使用,防止重复执行。

其他

scheduler 对象还有一些常用方法:

  • scheduler.remove_job(job_id) 删除任务
  • scheduler.pause_job(job_id) 暂停任务
  • scheduler.resume_job(job_id) 继续执行暂停任务
  • scheduler.modify_job(job_id) 修改定时任务(可以修改除了id外的属性,例如定时器等参数)
  • scheduler.get_jobs() 获取所有定时任务
  • scheduler.get_job(job_id) 获取特定任务
  • scheduler.print_jobs() 打印格式化的任务列表

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/254322.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【HarmonyOS应用开发】APP应用的通知(十五)

相关介绍 通知旨在让用户以合适的方式及时获得有用的新消息,帮助用户高效地处理任务。应用可以通过通知接口发送通知消息,用户可以通过通知栏查看通知内容,也可以点击通知来打开应用,通知主要有以下使用场景: 显示接收…

HiveSQL——用户中两人一定认识的组合数

注:参考文章: SQL之用户中两人一定认识的组合数--HQL面试题36【快手数仓面试题】_sql面试题-快手-CSDN博客文章浏览阅读1.2k次,点赞3次,收藏12次。目录0 需求分析1 数据准备2 数据分析3 小结0 需求分析设表名:table0现…

JRebel激活-nginx版本

nginx转发流量(代替其他网上说的那个工具) proxy_pass http://idea.lanyus.com; 工具激活 填写内容说明: 第一行的激活网址是:http://127.0.0.1:8888/ 正确的GUID。GUID 可以通过专门的网站来生成(点击打开&#…

Vue3快速上手(一)使用vite创建项目

一、准备 在此之前,你的电脑,需要安装node.js,我这边v18.19.0 wangdymb 2024code % node -v v18.19.0二、创建 执行npm create vuelatest命令即可使用vite创建vue3项目 有的同学可能卡主不动,可能是npm的registry设置的问题 先看下&#x…

Qt PCL学习(二):点云读取与保存

注意事项 版本一览:Qt 5.15.2 PCL 1.12.1 VTK 9.1.0前置内容:Qt PCL学习(一):环境搭建 0. 效果演示 1. pcl_open_save.pro QT core guigreaterThan(QT_MAJOR_VERSION, 4): QT widgets// 添加下行代码&#…

npm 下载报错

报错信息 : 证书过期 (CERT_HAS_EXPIRED) D:\Apps\nodejs-v18.16.1\npx.cmd --yes create-next-app"latest" . --ts npm ERR! code CERT_HAS_EXPIRED npm ERR! errno CERT_HAS_EXPIRED npm ERR! request to https://registry.npm.taobao.org/create-next-app failed…

7机器人位姿的数学描述与坐标变

由上次刚体的空间转动直接切换为机器人相关术语。 1.机器人位姿的数学描述与坐标变换 1.1位姿描述 {B}相对于{A}的姿态描述用3x3矩阵表示为: 式中为三个单位正交主矢量,分别表示刚体坐标系{B}的三个坐标轴XBYBZB在参考系{A}中的方位,∠XBXA表…

Git 消除对某个文件的追踪

参考: (尚未验证他的该方法) https://www.golinuxcloud.com/git-remove-file-from-tracking/https://www.golinuxcloud.com/git-remove-file-from-tracking/

第4节、电机多段转动【51单片机+L298N步进电机系列教程】

↑↑↑点击上方【目录】,查看本系列全部文章 摘要:本节介绍用控制步进电机三个主要参数角度、速度、方向,实现简单的步进电机多段控制 一、目标功能 输入多个目标角度,以及每个角度对应的速度,实现步进电机的多段多速…

TCP/IP协议以及UDP(超详细,看这一篇就够了)

💓 博客主页:从零开始的-CodeNinja之路 ⏩ 收录专栏:TCP/IP协议以及UDP(超详细,看这一篇就够了) 🎉欢迎大家点赞👍评论📝收藏⭐文章 TCP/IP协议以及UDP(超详细,看这一篇就够了 前提概括接收端和发送端客户…

【数据分享】1929-2023年全球站点的逐月平均能见度(Shp\Excel\免费获取)

气象数据是在各项研究中都经常使用的数据,气象指标包括气温、风速、降水、能见度等指标,说到气象数据,最详细的气象数据是具体到气象监测站点的数据! 之前我们分享过1929-2023年全球气象站点的逐月平均气温数据、逐月最高气温数据…

CSP-202112-1-序列查询

CSP-202112-1-序列查询 提示:若存在区间[i,j) 满足:f(i)f(i1)…f(j-1),使用乘法运算 f(i)x(j-i)代替将 f()到 f(j- 1)逐个相加,或可大幅提高算法效率。 一定要看提示!单纯的模拟时间会超限!算法也是根据提示设计的。 …

【Web】vulhub Fastjson反序列化漏洞复现学习笔记

目录 1.2.24 RCE CVE-2017-18349 复现流程 原理分析 1.2.47 RCE CNVD-2019-22238 复现流程 原理分析 漏洞探测 1.2.24 RCE CVE-2017-18349 复现流程 vulhub启动靶场 用marshalsec启动LDAP/RMI服务 java -cp marshalsec-0.0.3-SNAPSHOT-all.jar marshalsec.jndi.LDAPRef…

【每日一题】LeetCode——链表的中间结点

📚博客主页:爱敲代码的小杨. ✨专栏:《Java SE语法》 | 《数据结构与算法》 | 《C生万物》 ❤️感谢大家点赞👍🏻收藏⭐评论✍🏻,您的三连就是我持续更新的动力❤️ 🙏小杨水平有…

LabVIEW网络测控系统

LabVIEW网络测控系统 介绍了基于LabVIEW的网络测控系统的开发与应用,通过网络技术实现了远程的数据采集、监控和控制。系统采用LabVIEW软件与网络通信技术相结合,提高了系统的灵活性和扩展性,适用于各种工业和科研领域的远程测控需求。 随着…

机器学习:回归决策树(Python)

一、平方误差的计算 square_error_utils.py import numpy as npclass SquareErrorUtils:"""平方误差最小化准则,选择其中最优的一个作为切分点对特征属性进行分箱处理"""staticmethoddef _set_sample_weight(sample_weight, n_samp…

FlinkSql 窗口函数

Windowing TVF 以前用的是Grouped Window Functions(分组窗口函数),但是分组窗口函数只支持窗口聚合 现在FlinkSql统一都是用的是Windowing TVFs(窗口表值函数),Windowing TVFs更符合 SQL 标准且更加强大…

第5章 数据库操作

学习目标 了解数据库,能够说出数据库的概念、特点和分类 熟悉Flask-SQLAlchemy的安装,能够在Flask程序中独立安装扩展包Flask-SQLAlchemy 掌握数据库的连接方式,能够通过设置配置项SQLALCHEMY_DATABASE_URI的方式连接数据库 掌握模型的定义…

rust语言tokio库底层原理解析

目录 1 rust版本及tokio版本说明1 tokio简介2 tokio::main2.1 tokio::main使用多线程模式2.2 tokio::main使用单线程模式 3 builder.build()函数3.1 build_threaded_runtime()函数新的改变功能快捷键合理的创建标题,有助于目录的生成如何改变文本的样式插入链接与图…

【开源】JAVA+Vue.js实现高校实验室管理系统

目录 一、摘要1.1 项目介绍1.2 项目录屏 二、研究内容2.1 实验室类型模块2.2 实验室模块2.3 实验管理模块2.4 实验设备模块2.5 实验订单模块 三、系统设计3.1 用例设计3.2 数据库设计 四、系统展示五、样例代码5.1 查询实验室设备5.2 实验放号5.3 实验预定 六、免责说明 一、摘…