如何使用 python 在 Django 应用程序中安排任务

How to use python to schedule tasks in a Django application

总的来说,我是 Django 和 Web 框架的新手。我有一个应用程序,它已全部设置好并且在我的本地主机上运行良好。

该程序使用 Twitter 的 API 收集大量推文并将它们显示给用户。唯一的问题是我需要我的 python 程序让推文经常在后台 运行。

这是使用调度模块有意义的地方,但是一旦我启动本地服务器,它就永远不会 运行 调度功能。我试着阅读有关 cronjobs 的文章,但似乎无法让它发挥作用。如何让 Django 定期 运行 一个特定的 python 文件?

我遇到过类似的情况,并且在 django-apscheduler 上取得了很大的成功。它是独立的——它 运行 与 Django 服务器一起使用,并且在 Django 数据库中跟踪作业,因此您不必配置任何外部 cron 作业或任何调用脚本的东西。

下面是快速启动和 运行ning 的基本方法,但此 post 末尾的链接包含更多文档和详细信息以及更多高级选项。

使用 pip install django-apscheduler 安装,然后将其添加到您的 INSTALLED_APPS:

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

安装后,确保 运行 makemigrationsmigrate 在数据库上。

创建一个 scheduler python 包(在您的应用程序目录中的一个名为 scheduler 的文件夹,其中有一个空白 __init__.py)。然后,在其中创建一个名为 scheduler.py 的文件,该文件应如下所示:

from apscheduler.schedulers.background import BackgroundScheduler
from django_apscheduler.jobstores import DjangoJobStore, register_events
from django.utils import timezone
from django_apscheduler.models import DjangoJobExecution
import sys

# This is the function you want to schedule - add as many as you want and then register them in the start() function below
def deactivate_expired_accounts():
    today = timezone.now()
    ...
    # get accounts, expire them, etc.
    ...


def start():
    scheduler = BackgroundScheduler()
    scheduler.add_jobstore(DjangoJobStore(), "default")
    # run this job every 24 hours
    scheduler.add_job(deactivate_expired_accounts, 'interval', hours=24, name='clean_accounts', jobstore='default')
    register_events(scheduler)
    scheduler.start()
    print("Scheduler started...", file=sys.stdout)

在您的 apps.py 文件中(如果不存在则创建它):

from django.apps import AppConfig

    class AppNameConfig(AppConfig):
        name = 'your_app_name'
        def ready(self):
            from scheduler import scheduler
            scheduler.start()

注意事项:在 settings.py 文件中将其与 DEBUG = True 一起使用时,运行 开发服务器设置了 --noreload 标志(即 python manage.py runserver localhost:8000 --noreload), 否则计划任务将启动并 运行 两次。

此外,django-apscheduler 不允许您将任何参数传递给预定为 运行 的函数。这是一个限制,但我从来没有遇到过问题。如果确实需要,您可以从一些外部源加载它们,例如 Django 数据库。

您可以在 apscheduler 任务(函数)中使用所有标准的 Django 库、包和函数。比如查询模型,调用外部API,解析responses/data等等,无缝集成。

一些附加链接:

您可以使用的另一个库是 django-q

Django Q is a native Django task queue, scheduler and worker application using Python multiprocessing. 1

django-appscheduler 一样,它可以 运行 并使用 Django 附加的数据库跟踪作业。或者,它可以使用像 Reddis 这样的成熟代理。

The only problem is I need my python program that gets the tweets to be run in the background every-so-often.

这听起来像一个调度程序。 (Django-q 也有一个任务功能,它可以由事件触发而不是 运行 在一个时间表上。调度程序只是位于任务功能之上,并按定义的时间表触发任务。)

django-q 分为三个部分:

  1. 安装并配置 Django-q;
  2. 定义要获取推文的任务函数(或函数集);
  3. 定义 运行 任务的时间表;
  4. 运行 将处理计划和任务的 django-q 集群。

安装django-q

pip install django-q

在 Django 中将其配置为已安装的应用程序 settings.py(将其添加到安装应用程序列表):

INSTALLED_APPS = [
    ...
    'django_q',
    ...
]

然后它需要它自己的配置settings.py(这是一个使用数据库作为代理而不是 reddis 或 Django 外部的东西的配置。)

# Settings for Django-Q
# https://mattsegal.dev/simple-scheduled-tasks.html

Q_CLUSTER = {
    'orm': 'default',  # should use django's ORM and database as a broker.
    'workers': 4,
    'timeout': 30,
    'retry': 60,
    'queue_limit': 50,
    'bulk': 10,
}

然后您需要 运行 迁移数据库以创建 django-q 使用的表:

python manage.py migrate

(这将在数据库中创建一堆计划和任务相关的表。可以通过 Django 管理面板查看和操作它们。)

定义任务函数

然后为你想要的 tasks 创建一个新文件 运行:

# app/tasks.py
def fetch_tweets():
    pass  # do whatever logic you want here

定义任务计划

我们需要将 schedule 到 运行 任务添加到数据库中。

python manage.py shell
from django_q.models import Schedule
Schedule.objects.create(
    func='app.tasks.fetch_tweets',  # module and func to run
    minutes=5,  # run every 5 minutes
    repeats=-1  # keep repeating, repeat forever
)

您不必通过 shell 执行此操作。您可以在 python 代码等模块中执行此操作。但您可能只需要创建一次计划。

运行集群

完成所有这些后,您需要 运行 将处理计划的集群。否则,如果没有 运行ning 集群,计划和任务将永远不会被处理。对 qcluster 的调用是阻塞调用。所以通常你想 运行 它在一个单独的 window 或来自 Django 服务器进程的进程中。

python manage.py qcluster

当它 运行 时,您会看到如下输出:

09:33:00 [Q] INFO Q Cluster fruit-november-wisconsin-hawaii starting.
09:33:00 [Q] INFO Process-1:1 ready for work at 11
09:33:00 [Q] INFO Process-1:2 ready for work at 12
09:33:00 [Q] INFO Process-1:3 ready for work at 13
09:33:00 [Q] INFO Process-1:4 ready for work at 14
09:33:00 [Q] INFO Process-1:5 monitoring at 15
09:33:00 [Q] INFO Process-1 guarding cluster fruit-november-wisconsin-hawaii
09:33:00 [Q] INFO Q Cluster fruit-november-wisconsin-hawaii running.

还有一些 example documentation 如果您想了解如何将任务与报告、电子邮件或信号等挂钩,那将非常有用。