在之前的文章中,我們通過 Django-Celery-Beat: 使用 PeriodicTask 進行排程任務的實戰範例 探討了如何管理 利用 IntervalSchedule 進行排程任務

然而,在實際專案中,僅僅依賴重複執行(interval)的方式往往不夠。

  • 當需要在特定時間執行的任務
  • 當需要在特定日期和時間僅執行一次的任務

在這種情況下,使用 Crontab 或者 Clocked 的排程方式可以設置更加精密的排程任務。 🚀

📌 對 Crontab 的概念不熟悉嗎?

➡️ 深入理解 Linux `crontab`: 開發者喜愛的自動排程秘訣

先閱讀上述文章會更容易理解! 😊

Django Celery-Beat task scheduling with Crontab and Clocked

1️⃣ 利用 `CrontabSchedule` 設置特定時間的排程

Crontab 是 Linux 中使用的排程方式,可以設定於特定時間執行的任務,如秒/分鐘/小時/星期/日期等

在 Django-Celery-Beat 中也可以利用 `CrontabSchedule` 以同樣的方式設定排程任務。

📌 範例: 每天上午 9 點 30 分執行的排程任務

from django_celery_beat.models import PeriodicTask, CrontabSchedule
import json

# 1️⃣ 創建 CrontabSchedule (每天 09:30 執行)
schedule, created = CrontabSchedule.objects.get_or_create(
    minute="30",
    hour="9",
    day_of_week="*",
    day_of_month="*",
    month_of_year="*"
)

# 2️⃣ 創建或更新 PeriodicTask
task, created = PeriodicTask.objects.update_or_create(
    name="daily_report_task",
    defaults={
        "crontab": schedule,  # 應用 CrontabSchedule
        "task": "myapp.tasks.generate_daily_report",
        "args": json.dumps([]),
        "enabled": True,
    }
)

✅ 上述設定將使任務於每天上午 9 點 30 分執行! 🎯

✅ `CrontabSchedule` 欄位解釋

欄位名稱 說明 範例
`minute` 設定執行的分鐘 "0", "30", "*/10"
`hour` 設定執行的時鐘 "0", "9", "*/6"
`day_of_week` 設定執行的星期(0=星期日) "*"(每天),`"1,3,5"`(一/三/五)
`day_of_month` 設定執行的日期 "*"(每天),`"1,15"`(每月 1 日、15 日)
`month_of_year` 設定執行的月份 "*"(每月),`"1,6,12"`(1 月、6 月、12 月)

2️⃣ 利用 `ClockedSchedule` 設定在特定時間執行一次

`ClockedSchedule` 用於設定在特定日期和時間僅執行一次的排程任務。

📌 範例: 在特定日期(2025 年 2 月 10 日 15:00)僅執行一次的排程任務

from django_celery_beat.models import PeriodicTask, ClockedSchedule
import json
from datetime import datetime

# 1️⃣ 創建 ClockedSchedule (於 2025 年 2 月 10 日 15:00 執行)
scheduled_time = datetime(2025, 2, 10, 15, 0)  # 必須使用 datetime 物件!
schedule, created = ClockedSchedule.objects.get_or_create(
    clocked_time=scheduled_time
)

# 2️⃣ 創建 PeriodicTask (設置 one_off=True!)
task, created = PeriodicTask.objects.update_or_create(
    name="one_time_task_20250210",
    defaults={
        "clocked": schedule,  # 應用 ClockedSchedule
        "task": "myapp.tasks.one_time_email",
        "args": json.dumps([]),
        "enabled": True,
        "one_off": True,  # 執行後自動禁用
    }
)

✅ 上述設定會於2025 年 2 月 10 日 15 點 00 分執行一次,然後自動禁用

  • 📌 創建 ClockedSchedule 模型的實例時,clocked_time 欄位必須輸入為 datetime 物件。
  • 📌 若使用字符串或其他數據類型則可能會發生錯誤。

📌 ClockedSchedule 與 one_off 選項之間的關係?

當在 ClockedSchedule 中創建僅執行一次的任務時需要設置 one_off=True
您可能會好奇該設置如何與 enabled 欄位互動。

📌 想更深入了解這兩個欄位(clocked_timeone_off)之間的關係嗎?

➡️ Celery Beat 中 one-off 和 enabled 的關係:正確理解和使用方法

在上述文章中,關於 one_off=True 是如何運作的,以及 enabled 有什麼區別進行了深入探討,請參考! 😊

🎯 結論:利用 CrontabClocked 可以設置更加精密的排程任務!

  • 利用 CrontabSchedule 可以設定重複但在特定時間執行的任務
  • 利用 ClockedSchedule 可以設定在特定時刻僅執行一次的任務
  • 創建 ClockedSchedule 時,clocked_time 欄位必須輸入 datetime 物件!
  • ClockedSchedule 和 one_off=True 設定之間的關係將在另外一篇文章中深入探討,敬請期待!

如果您想了解更深入的 Celery 使用方法,

請查看下面的「相似文章」列表或在右上角的搜索框中搜索『Celery』! 🚀 😊