13

我需要创建一个每天从 crontab 发送时事通讯的功能。我在互联网上找到了两种方法:

首先 - 放置在 django 项目文件夹中的文件:

#! /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 ,['user@example.com'])

if __name__ == '__main__':
    main()

我不确定它是否会起作用,也不知道如何运行它。假设它被称为 run.py,那么我应该在 cron 中调用它0 0 * * * python /path/to/project/run.py 吗?

第二种解决方案 - 在任何地方创建我的发送函数(就像普通的 django 函数一样),然后创建一个 run.py 脚本:

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()

哪种方法可行,或者哪种方法更好?

4

7 回答 7

37

我建议将您的功能创建为django-management-command并通过 crontab 运行它

如果您的命令很send_newsletter简单

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

在这种情况下,您无需设置设置模块/

于 2010-07-08T03:08:19.857 回答
10

Ashok 关于通过 cron 运行管理命令的建议效果很好,但是如果您正在寻找更强大的东西,我会研究像Kronos这样的库:

# app/cron.py

import kronos

@kronos.register('0 * * * *')
def task():
    pass
于 2011-12-20T12:27:00.523 回答
3

我建议看看django-chronograph。基本上,它以与其他建议类似的方式执行您想要的操作 + 它使您可以通过管理面板管理您的 cron 作业。Cron 作业必须作为 django 命令实现。然后,您可以通过调用运行所有挂起的作业

python manage.py cron

这应该由您的 cron 触发。

于 2011-01-10T10:58:59.190 回答
1

还有django-cron。它使用起来非常简单,无需安装或设置其他任何东西。

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

于 2010-07-08T09:32:09.583 回答
1

我推荐选项 3:在django-extensions中使用作业系统。相关的扩展命令是:

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

这使您可以管理 Django 内部的所有作业处理,因此您不必一直弄乱 crontab。

于 2010-07-08T01:37:26.747 回答
1

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

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

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

无论如何, PEP 8不鼓励相对进口。

我总是将我的 Django 应用程序安装在站点包中(/usr/lib64/python2.6/site-packages在 Gentoo 上),所以我不必担心PYTHONPATH从我的 crontab 中进行设置,但我不认为这是一种广泛使用的方法。我还喜欢使用setuptools 自动创建脚本,以便我的控制台脚本可以放在它们应该放在的任何位置(/usr/bin例如 ),并自动适当地命名。您的第一个选项也有助于实现这一点。

于 2010-07-08T04:09:05.357 回答
0

选项 1 对我有用。我通常将脚本 cd 到项目目录,然后执行“python ./script_name.py”,这样就没有神秘的路径问题......懒惰,但它始终如一地工作。

于 2010-07-08T05:22:06.273 回答