django 定時任務第三方庫apscheduler


1、apscheduler未安裝的需要自己安裝,安裝命令如下:

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) 指定時區

# 導入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,范圍是年月日的組合字符串

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 所有 組合表達式,可以組合確定值或上方的表達式

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()

  

示例:

#封裝郵件發送方法
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

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM