关于python:将crontab与django一起使用

Using crontab with django

本问题已经有最佳答案,请猛点这里访问。

我需要创建一个从crontab每天发送新闻稿的函数。我在网上找到了两种方法:

第一个文件放在Django项目文件夹中:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
#! /usr/bin/env python
import sys
import os

from django.core.management import setup_environ
import settings
setup_environ(settings)

from django.core.mail import send_mail
from project.newsletter.models import Newsletter, Address

def main(argv=None):
    if argv is None:
        argv = sys.argv

    newsletters = Newsletter.objects.filter(sent=False)
    message = 'Your newsletter.'

    adr = Address.objects.all()
    for a in adr:
        for n in newsletters:
            send_mail('System report',message, a ,['[email protected]'])

if __name__ == '__main__':
    main()

我不确定它是否会起作用,也不确定如何运行它。假设它是run.py,那么我应该用cron和0 0 * * * python /path/to/project/run.py
来称呼它吗?

第二个解决方案-在任意位置创建发送函数(就像普通的django函数),然后创建run.py脚本:

1
2
3
4
5
6
7
8
9
10
import sys
import os

os.environ['DJANGO_SETTINGS_MODULE'] = 'settings'

module_name = sys.argv[1]
function_name = ' '.join(sys.argv[2:])

exec('import %s' % module_name)
exec('%s.%s' % (module_name, function_name))

然后在cron调用中:0 0 * * * python /path/to/project/run.py newsletter.views daily_job()

哪种方法有效,哪种更好?


我建议将您的功能创建为django管理命令,并通过crontab运行它。

如果你的命令是send_newsletter,那么简单地

1
0 0 * * * python /path/to/project/manage.py send_newsletter

在这种情况下,您不需要关心设置模块的设置。/


Ashok关于通过cron运行管理命令的建议很好,但是如果您要寻找一个更健壮的东西,我会查找类似kronos的库:

1
2
3
4
5
6
7
# app/cron.py

import kronos

@kronos.register('0 * * * *')
def task():
    pass


我建议看一下姜戈计时手表。基本上,它以一种非常简单的方式执行您想要的其他建议+它使您能够通过管理面板管理您的cron作业。cron作业必须作为django命令实现。然后,您可以通过调用

1
python manage.py cron

它应该由你的亲信触发。


还有姜戈·克罗恩。它的使用非常简单,没有其他安装或设置。

但是,我不确定它到底是如何工作的…我的意思是,我不知道这些作业是如何运行的,也不知道当没有人向站点提出请求时,它们是否运行。但你可以试试看!


我使用与第一个选项类似的方法编写了一些命令行应用程序。我更喜欢这样做,而不是使用DJANGO_SETTINGS_MODULE环境变量,因为它感觉更像一个常规的Python程序(对我来说)。

还应注意,您不必将模块放在与settings.py相同的目录中;您可以使用设置模块的绝对python路径:

1
2
3
4
from django.core.management import setup_environ
from project import settings
setup_environ(settings)
#The rest of your imports

无论如何,PEP8都不鼓励相对进口。

我总是将我的django应用程序安装在站点包(gentoo上的/usr/lib64/python2.6/site-packages中),所以我不必担心从crontabs设置PYTHONPATH,但我不认为这是一种广泛使用的方法。我还喜欢使用设置工具自动创建脚本,这样我的控制台脚本就可以放在应该放在的地方(例如,/usr/bin),并且可以自动命名。您的第一个选项也有助于实现这一点。


我建议选项3:在Django扩展中使用作业系统。相关的扩展命令是:

  • create_jobs–为当前目录中给定的应用程序名创建django jobs命令目录结构。这是令人印象深刻的工作制度的一部分。
  • runjob–运行单个维护作业。作业系统的一部分。
  • runjobs–运行计划的维护作业。指定每小时、每天、每周、每月。作业系统的一部分。

这可以让您管理Django内部的所有工作处理,因此您不必一直与crontab打交道。


选项1适用于我。我通常把脚本cd放在项目目录下,然后做"python./scriptame.py",这样就不会有神秘的路径问题了…懒惰,但它能始终如一地工作。