Использование crontab с django

Мне нужно создать функцию для ежедневного рассылки бюллетеней из 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 ,['[email protected]'])

if __name__ == '__main__':
    main()

Я не уверен, что это сработает, и я не уверен, как его запустить. Скажем, он называется run.py, поэтому я должен называть его в cron с помощью 0 0 * * * python /path/to/project/run.py ?

Второе решение - создайте мою функцию отправки в любом месте (как обычную функцию django), а затем создайте run.py script:

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

Какой метод будет работать, или что лучше?

Ответ 1

Я предлагаю создать вашу функциональность как django-management-command и запустить ее через crontab

если ваша команда send_newsletter, а затем просто

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

и вам не нужно заботиться о настройке модуля настроек в этом случае/

Ответ 2

Предложение Ashok об управлении командами управления через cron работает хорошо, но если вы ищете что-то более надежное, я бы посмотрел в библиотеку, например Kronos:

# app/cron.py

import kronos

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

Ответ 3

Предлагаю взглянуть на django-chronograph. В основном, он делает то, что вы хотите, в соответствии с другими предложениями +, это дает вам возможность управлять вашими заданиями cron через панель администратора. Работы Cron должны выполняться как команды django. Затем вы можете запускать все ожидающие задания, вызывая

python manage.py cron

который должен быть вызван вашим cron.

Ответ 4

Я бы рекомендовал вариант 3: используйте систему заданий в django-extensions. Соответствующими командами расширения являются:

  • create_jobs - Создает структуру каталога команд заданий Django для данного имени приложения в текущем каталоге. Это часть впечатляющей системы рабочих мест.
  • runjob - выполните одно задание на обслуживание. Часть системы рабочих мест.
  • runjobs - выполняет запланированные задания по техническому обслуживанию. Укажите ежечасно, ежедневно, еженедельно, ежемесячно. Часть системы рабочих мест.

Это позволяет вам управлять всей обработкой заданий внутри Django, поэтому вам не нужно продолжать возиться с crontab.

Ответ 5

Я написал несколько приложений с командной строкой, используя метод, аналогичный вашему первому варианту. Я предпочитаю делать это таким образом, в отличие от использования переменной среды 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 Automatic Script Creation, чтобы мои консольные скрипты попадали туда, где они должны быть (/usr/bin, например) и называются соответственно автоматически. Ваш первый вариант также облегчает это.

Ответ 6

Существует также django-cron. Он очень прост в использовании, нет ничего другого для установки или настройки.

Однако, я не уверен, как это работает... Я имею в виду, что я не знаю, как выполняются задания и, если они запущены на все, когда никто не делает запрос на сайт. Но вы можете попробовать!

Ответ 7

Вариант 1 работает для меня. Обычно я использую script cd для каталога проекта, а затем выполняю "python./script_name.py", чтобы не было таинственных проблем пути... ленив, но он работает последовательно.