python - django定时任务 - Django-设置计划任务?
django-crontab (13)
我一直在使用Django开发一个web应用程序,我很好奇是否有办法安排一项工作定期运行。
基本上我只想运行数据库并自动定期进行一些计算/更新,但我似乎无法找到任何有关执行此操作的文档。
有谁知道如何设置?
澄清:我知道我可以设置一个cron
工作来完成这个任务,但是我很好奇Django中是否有一些功能可以提供这种功能。 我希望人们能够自己部署这个应用程序,而无需做太多配置(最好是零)。
我曾考虑通过简单地检查自上次向网站发送请求之后是否应该运行一项工作来触发这些“追溯性”操作,但我希望能够做得更干净些。
Brian Neal的建议是通过cron运行管理命令,但如果你正在寻找一些更强大的功能(但不像Celery那样精致),我会考虑像Kronos这样的库:
# app/cron.py
import kronos
@kronos.register('0 * * * *')
def task():
pass
RabbitMQ和Celery比Cron有更多的功能和任务处理能力。 如果任务失败不是问题,并且您认为您将在下次调用中处理中断的任务,那么Cron就足够了。
Celery和AMQP可以让你处理破碎的任务,并且它会被另一个工人再次执行(Celery工作人员监听下一个任务),直到达到任务的max_retries
属性。 您甚至可以调用失败时的任务,例如记录失败,或者在达到max_retries
向管理员发送电子邮件。
当需要扩展应用程序时,您可以分发Celery和AMQP服务器。
与Celery相比,更现代的解决方案是Django Q: https://django-q.readthedocs.io/en/latest/index.html : https://django-q.readthedocs.io/en/latest/index.html
它有很好的文档,很容易理解。 缺少Windows支持,因为Windows不支持进程分叉。 但是,如果使用Windows for Linux子系统创建开发环境,则工作正常。
前段时间我的要求完全一样,最后使用APScheduler ( 用户指南 )解决问题。
它使调度工作变得非常简单,并保持它独立于某些代码的基于请求的执行。 以下是我在代码中使用的一个简单示例。
from apscheduler.schedulers.background import BackgroundScheduler
scheduler = BackgroundScheduler()
job = None
def tick():
print('One tick!')\
def start_job():
global job
job = scheduler.add_job(tick, 'interval', seconds=3600)
try:
scheduler.start()
except:
pass
希望这可以帮助别人!
如果您使用的是标准POSIX OS,则使用cron 。
如果您使用的是Windows,则可以使用。
写一个Django管理命令
找出他们在哪个平台上。
要么为您的用户执行适当的“AT”命令,要么为您的用户更新crontab。
将以下内容放在cron.py文件的顶部:
#!/usr/bin/python
import os, sys
sys.path.append('/path/to/') # the parent directory of the project
sys.path.append('/path/to/project') # these lines only needed if not on path
os.environ['DJANGO_SETTINGS_MODULE'] = 'myproj.settings'
# imports and code below
我个人使用cron,但django-extensions的Jobs Scheduling部分看起来很有趣。
我今天有类似的问题。
我不想让服务器处理cron(并且大多数库只是最后的cron助手)。
所以我创建了一个调度模块并将其附加到init 。
这不是最好的方法,但它可以帮助我将所有代码放在一个地方,并将其执行与主应用程序相关联。
我只是想到了这个相当简单的解决方案:
- 像使用其他视图一样定义视图函数do_work(req,param) ,使用URL映射,返回HttpResponse等。
- 使用运行curl http://localhost/your/mapped/url?param=value的计时首选项(或使用AT或Windows中的计划任务)设置cron作业。
您可以添加参数,但只需向URL添加参数即可。
告诉我你们的想法。
[更新]我现在使用django-extensions runjob命令而不是curl。
我的cron看起来像这样:
@hourly python /path/to/project/manage.py runjobs hourly
...等等每日,每月等“。 您也可以设置它来运行特定的工作。
我觉得它更可管理,更清洁。 不需要将URL映射到视图。 只需定义你的工作类和crontab,然后设置好。
我用芹菜来创造我的定期任务。 首先,您需要按如下方式安装它:
pip install django-celery
不要忘记在你的设置中注册django-celery
,然后你可以做这样的事情:
from celery import task
from celery.decorators import periodic_task
from celery.task.schedules import crontab
from celery.utils.log import get_task_logger
@periodic_task(run_every=crontab(minute="0", hour="23"))
def do_every_midnight():
#your code
是的,上面的方法非常棒。 我尝试了其中的一些。 最后,我找到了这样一个方法:
from threading import Timer
def sync():
do something...
sync_timer = Timer(self.interval, sync, ())
sync_timer.start()
就像递归一样。
好的,我希望这种方法能够满足你的要求。 :)
有趣的新插件Django应用程序: django-chronograph
您只需添加一个充当计时器的cron条目,并且您可以在要运行的脚本中拥有一个非常好的Django管理界面。