如何在 Django 应用程序中使用 python 调度任务

awo*_*ldt 3 python django scheduled-tasks

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

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

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

Mik*_*ins 9

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

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

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

INSTALLED_APPS = [
    ...
    'django_apscheduler',
    ...
]
Run Code Online (Sandbox Code Playgroud)

安装后,请确保在数据库上运行makemigrations和migrate。

创建一个schedulerpython 包(应用程序目录中的一个文件夹,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)
Run Code Online (Sandbox Code Playgroud)

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

from django.apps import AppConfig

    class AppNameConfig(AppConfig):
        name = 'your_app_name'
        def ready(self):
            from scheduler import scheduler
            scheduler.start()
Run Code Online (Sandbox Code Playgroud)

提醒一句:DEBUG = True在您的settings.py文件中使用它时,请在--noreload设置了标志(即python manage.py runserver localhost:8000 --noreload)的情况下运行开发服务器,否则计划任务将启动并运行两次。

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

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

一些额外的链接:

  • 我建议在 add_job 调用中添加 id="some_id" 以防止每次启动时重复作业 (2认同)
  • 除了 Michael 的警告之外:您还可以在“ready()”方法中检查“RUN_MAIN”环境变量,在第二次迭代中它等于“True”。这种干净简单的解决方法允许您保持开发服务器重新加载。 (2认同)
  • 另外,不要忘记在应用程序的 __init__.py` 中设置默认应用程序配置:``default_app_config = 'myApp.apps.myAppConfig'``` (2认同)