詳解django-apscheduler的使用方法

若是你在使用Django框架開發web項目時,須要設置定時任務或讓用戶手動在頁面上設置定時任務,那麼這篇文章可能會幫助到你。前端

概述

在Django中實現定時任務功能大概有如下三種方法:python

Celery框架

定時任務是分佈式任務的一種特殊類型的任務。Django的分佈式主要由Celery框架實現,這是python開發的分佈式任務隊列。因爲它自己不支持消息存儲服務,因此須要第三方消息服務來傳遞任務,通常使用Redis。mysql

優勢:linux

  1. Celery側重於實時操做,可用於生產系統天天處理數以百萬計的任務,可用於大型項目。
  2. 可在分佈的機器、進程、線程上執行任務調度。

缺點:web

配置和使用較爲複雜,須要Redis數據庫和多個python第三方庫。sql

django-crontab

只須要下載一個 django-crontab 包就可使用cron表達式在Django框架中設置定時任務。本人對這種方法瞭解很少,不過這種方法好像不支持windows系統,功能也相對簡單。數據庫

django-apscheduler

配置簡單、功能齊全、使用靈活、支持windows和linux,適合中小型項目。django

使用方法

django-apscheduler中相關的概念和python的定時任務框架apscheduler中的概念是同樣的,有感興趣的同窗能夠自行查閱。json

(本文使用 django + mysql 架構)windows

安裝模塊

pip install django-apscheduler
複製代碼

配置

  1. 先在settings.py中配置好數據庫信息(略).
  2. INSTALLED_APPS中加入django-apscheduler應用:
INSTALLED_APPS = [
        ...
        'django_apscheduler',
        ...
    ]
複製代碼

執行遷移

python manage.py migrate
複製代碼

去數據庫中看一看,生成了兩個表格,大部分都顧名思義。

1. django_apscheduler_djangojob

用於存儲任務的表格

job_state: 我猜是將任務具體的執行代碼和參數進行序列化後存在了這裏

2. django_apscheduler_djangojobexecution

用於存儲任務執行狀態的表格

status: 執行狀態
duration: 執行了多長時間
exception: 是否出現了什麼異常

使用

建立任務

大概有兩種建立任務的方法:裝飾器和add_job函數。

1. 裝飾器

在任意view.py中實現代碼(我習慣新開一個app專門實現定時任務):

from apscheduler.schedulers.background import BackgroundScheduler
from django_apscheduler.jobstores import DjangoJobStore, register_events, register_job

# 實例化調度器
scheduler = BackgroundScheduler()
# 調度器使用默認的DjangoJobStore()
scheduler.add_jobstore(DjangoJobStore(), 'default')

# 天天8點半執行這個任務
@register_job(scheduler, 'cron', id='test', hour=8, minute=30,args=['test'])
def test(s):
    # 具體要執行的代碼
    pass

# 註冊定時任務並開始
register_events(scheduler)
scheduler.start()
複製代碼

啓動服務 python manage.py runserver 這個任務就會被存儲到django_apscheduler_djangojob表中,並按照設置定時的執行程序。

參數

  • scheduler: 指定調度器
  • trigger: 任務執行的方式,共有三種: 'date'、'interval'、'cron'。
    • 'date' + 'run_date' 的參數組合, 能實現單次任務
      例子: 2019-07-07 22:49:00 執行任務
      @register_job(scheduler, 'date', id='test', run_date='2019-07-07 22:49:00')
      注:在親測時,執行完任務會報錯,緣由時執行完任務後會去mysql中刪除djangojob表中的任務。可是djangojobexecution表記錄着執行結果,有外鍵關聯着djangojob表,因此刪除時顯示有外鍵約束錯誤。可是任務會正常執行,執行以後也會正常刪除。
    • 'interval' + 'hours' + 'minutes' + ..... 的參數組合,能實現間隔性任務
      例子:每隔3個半小時執行任務
      @register_job(scheduler, 'interval', id='test', hours=3, minutes=30)
      還有seconds,days參數能夠選擇
      注:若是任務須要執行10秒,而間隔設置爲1秒,它是不會給你開10個線程同時去執行10個任務的。它會錯過其餘任務直到當前任務完成。
    • 'cron' + 'hour' + 'minute'+...的參數組合,能實現cron類的任務
      例子:天天的8點半執行任務
      @register_job(scheduler, 'cron', id='test', hour=8, minute=30)
      還有day,second,month等參數能夠選擇。
  • id: 任務的名字,不傳的話會自動生成。不過爲了以後對任務進行暫停、開啓、刪除等操做,建議給一個名字。而且是惟一的,若是多個任務取一個名字,以前的任務就會被覆蓋。
  • args: list類型。執行代碼所須要的參數。
  • next_run_time:datetime類型。開始執行時間。若是你如今建立一個定時任務,想3天后凌晨三點半自動給你女友發微信,那就須要這個參數了。

還有些其餘的參數感興趣的同窗能夠查看源代碼來了解。

2. add_job函數

裝飾器的方法適合於寫代碼的人本身建立任務,若是想讓用戶經過頁面輸入參數,並提交來手動建立定時任務,就須要使用add_job函數。
下面這個小例子,前端傳遞json數據給後端,觸發test_add_task函數,來添加任務:

import json
from django.http import JsonResponse
from apscheduler.schedulers.background import BackgroundScheduler
from django_apscheduler.jobstores import DjangoJobStore, register_events, register_job


scheduler = BackgroundScheduler()
scheduler.add_jobstore(DjangoJobStore(), 'default')

# 與前端的接口
def test_add_task(request):
    if request.method == 'POST':
        content = json.loads(request.body.decode())  # 接收參數
        try:
            start_time = content['start_time']  # 用戶輸入的任務開始時間, '10:00:00'
            start_time = start_time.split(':')
            hour = int(start_time)[0]
            minute = int(start_time)[1]
            second = int(start_time)[2]
            s = content['s']  # 接收執行任務的各類參數
            # 建立任務
            scheduler.add_job(test, 'cron', hour=hour, minute=minute, second=second, args=[s])
            code = '200'
            message = 'success'
        except Exception as e:
            code = '400'
            message = e
            
        back = {
            'code': code,
            'message': message
        }
        return JsonResponse(json.dumps(data, ensure_ascii=False), safe=False)
        
# 具體要執行的代碼
def test(s):
    pass
    

register_events(scheduler)
scheduler.start()
複製代碼

這樣就能夠由前端用戶來手動設置定時任務了。

參數

和裝飾器的參數大同小異,只是第一個參數不一樣。
若是具體要執行的函數和調用它的函數在一個文件中,那麼只須要傳遞這個函數名就能夠了(如上面的例子)。
可是我習慣將具體的業務代碼寫到另一個文件中,view.py中只寫先後端交互的接口函數,這種狀況下傳遞的參數爲一個字符串,格式爲: 'package.module:some.object',即 包名.模塊:函數名

其餘功能

django-apscheduler框架還提供了不少操做定時任務的函數。好比:

  • 刪除任務
    scheduler.remove_job(job_name)
  • 暫停任務
    scheduler.pause_job(job_name)
  • 開啓任務
    scheduler.resume_job(job_name)
  • 修改任務
    scheduler.modify_job(job_name)
    注:修改任務只能修改參數,若是要修改執行時間的話,就把任務刪了從新建立。

能夠在頁面上作一個這樣的表格,再加上簡單的先後端交互就可讓用戶自行管理定時任務:

其餘的還有一些輔助功能(包括顯示全部任務,顯示任務的執行時間等),同窗們能夠自行查看。 最後,感謝閱讀。

相關文章
相關標籤/搜索