django 定时任务第三方库apscheduler
1、apscheduler未安装的需要自己安装,安装命令如下:
1 | pip install apscheduler |
2、apscheduler库有很多不同类型的调度器,其他我也不懂,只知道BlockingScheduler与BackgroundScheduler,这是比较常用的两种
区别主要在于BlockingScheduler会阻塞主线程的运行,而BackgroundScheduler不会阻塞。所以,我们在不同的情况下,选择不同的调度器:
BlockingScheduler: 调用start函数后会阻塞当前线程。当调度器是你应用中唯一要运行的东西时使用(下面写的就是这种调度)
BackgroundScheduler: 调用start后主线程不会阻塞。当你不运行任何其他框架时使用,并希望调度器在你应用的后台执行
用人话说就是:用BlockingScheduler创建的类,调用start()函数开始运行后,会阻塞(相当于停止)当前已在运行的线程,只执行当前的定时任务,运行到你主动关掉为止
而BackgroundScheduler创建的类,调用start后主线程不会阻塞,会继续运行下一行代码,如果后面没有死循环什么的,订的时间又比较长,会出现定时还没生效,代码已经运行结束的情况
参考文章:https://www.cnblogs.com/will-wu/p/14721592.html
3、apscheduler的触发器
apscheduler的触发器有三种:date(日期触发),interval(固定间隔触发),cron(周期触发)
date表示具体的一次性任务,interval表示循环任务,cron表示定时任务
3.1、日期触发:date,特定的时间点触发,最基本的一种调度,作业只会执行一次
run_date(datetime or str) 任务运行的日期或者时间
timezone(datetime.tzinfo or str) 指定时区
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | # 导入BlockingScheduler调度器 from apscheduler.schedulers.blocking import BlockingScheduler from datetime import datetime # 封装函数待用 def print_hours_now(): print ( '小时:%s' % datetime.now().strftime( "%Y-%m-%d %H:%M:%S" )) # 创建一个对象 timing_type = BlockingScheduler() # run_date时间到了之后,开始执行print_hours_now timing_type.add_job(print_hours_now, 'date' ,run_date = '2021-04-30 16:13:00' ) # 或这样写 # timing_type.add_job(func=print_hours_now,trigger='date',run_date='2021-04-30 16:13:00') # 立即执行 timing_type.add_job(print_hours_now, 'date' ) # 等待触发时间到达,开始执行指定任务 timing_type.start() |
3.2、interval:固定间隔触发
year:每隔X年执行一次
weeks:每隔X周执行一次 weeks=X,范围1-12
days:每隔X天执行一次,范围1-31
hours: 每隔几小时执行一次 | hours=0,范围0-23
minutes: 每隔几分执行一次 | minutes=0,范围0-59
seconds: 每隔几秒执行一次 | seconds=0,范围0-59
start_date: 最早执行时间 | start_date=None,范围是年月日的组合字符串
end_date: 最晚执行时间 | end_date=None,范围是年月日的组合字符串
timezone: 执行时间区间 | timezone=None,范围是年月日的组合字符串
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | from apscheduler.schedulers.blocking import BlockingScheduler from datetime import datetime def print_minutes_now(): print ( '打印时间:%s' % datetime.now().strftime( "%Y-%m-%d %H:%M:%S" )) timing_type = BlockingScheduler() # 在start_date到end_date时间段内,每隔5s执行一次print_minutes_now;其中,func=这些可以省略,start_date和end_date可以单独使用, # timing_type.add_job(func=print_minutes_now,trigger='interval',seconds=5,start_date='2021-05-04 11:40',end_date='2021-05-04 11:41:00') # 在end_date之前,每隔0.2小时运行一次print_minutes_now timing_type.add_job(func = print_minutes_now,trigger = 'interval' ,minutes = 2 ,end_date = '2021-05-08 11:41:00' ) # 每隔1小时执行一次 timing_type.add_job(func = print_minutes_now,trigger = 'interval' ,hours = 1 ) # 启动调度器 timing_type.start() |
3.3、cron:周期触发,在特定时间周期性地触发
cron参数:
year(int or str) 年,4位数字
month(int or str) 月(范围1-12)
day(int or str) 日(范围1-31)
week(int or str) 周(范围1-53)
day_of_week(int or str) 周内第几天或者星期几(范围0-6或者mon,tue,wed,thu,fri,stat,sun)
hour(int or str) 时(0-23)
minute(int or str) 分(0-59)
second(int or str) 秒(0-59)
start_date(datetime or str) 最早开始日期(含)
end_date(datetime or str) 最晚结束日期(含)
timezone(datetime.tzinfo or str) 指定时区
表达式:
* 所有 通配符。例:minutes=*即每分钟触发
*/a 所有 可被a整除的通配符。
a-b 所有 范围a-b触发
a-b/c 所有 范围a-b,且可被c整除时触发
xth y 日 第几个星期几触发。x为第几个,y为星期几
last x 日 一个月中,最后个星期几触发
last 日 一个月最后一天触发
x,y,z 所有 组合表达式,可以组合确定值或上方的表达式
1 2 3 4 5 6 7 8 9 10 11 12 13 | from apscheduler.schedulers.blocking import BlockingScheduler from datetime import datetime def print_time_now(): print ( '打印当前时间:' ,datetime.now().strftime( "%Y-%m-%d %H:%M:%S" )) timing_type = BlockingScheduler() # 每个月每天的17:36,打印当前时间,*代表0-59 # timing_type.add_job(print_time_now,'cron',month='*',day='*',hour=17,minute=36,second='*') # 每天的每小时16分的零秒开始到59秒执行print_time_now(年月日时不写的时候会默认为所有,秒不写则默认为0) timing_type.add_job(func = print_time_now, trigger = 'cron' ,minute = '16' ,second = '0-59' ) # 周一到周五6:30执行timing_type.add_job(print_time_now, "cron",day_of_week = "1-5", hour = 6, minute = 30) # 启动调度器 timing_type.start() |
示例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 | #封装邮件发送方法 from django.core.mail import send_mail def send_email(email_user): send_mail( subject = '这里是邮件标题' , message = '这里是邮件内容' , from_email = 'test@qq.com' , # 发件人 recipient_list = [email_user], # 收件人 #收件人可以直接写,也可以从setting.py中配置中导入 fail_silently = False ) print ( "邮件发送成功" ) return "邮件已发送" #定时任务 from apscheduler.schedulers.background import BackgroundScheduler #待定时执行的函数 def update_days(): all_borrow_book = Borrow.objects. filter (borrow_status = 2 ) now = datetime.date.today() # all_bookname = all_borrow_book.book_id for book in all_borrow_book: id = book. id user_id = book.user_id book_id = book.book_id print ( "userid:" ,user_id) email_user = User.objects.get(username = user_id).email lib_book = Book.objects.get(book_number = book_id) update_book = Borrow.objects.get( id = id ) return_date = book.return_date update_days = return_date.__sub__(now).days update_book.surplus_days = update_days if update_days < 0 : update_book.borrow_status = - 1 update_book.save() lib_book.book_status = - 1 lib_book.save() send_email(email_user) else : update_book.save() print ( "surplus_days: " ,update_days) #开启定时工作 try : # 实例化调度器 scheduler = BackgroundScheduler() # scheduler.add_job(my_job, 'interval', minutes=10) scheduler.add_job(update_days, 'cron' ,month = '*' ,day = '*' ,hour = 19 ,minute = 38 ,second = 00 ) scheduler.start() except Exception as e: print (e) |
https://apscheduler.readthedocs.io/en/3.x/userguide.html#code-examples
https://www.cnblogs.com/will-wu/p/14731728.html
本文作者:香菜哥哥
本文链接:https://www.cnblogs.com/yizhipanghu/p/16083762.html
版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步