Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using crontab with django [duplicate]

I need to create a function for sending newsletters everyday from crontab. I've found two ways of doing this on the internet :

First - file placed in the django project folder:

#! /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()

I'm not sure if it will work and I'm not sure how to run it. Let's say it's called run.py, so should I call it in cron with 0 0 * * * python /path/to/project/run.py ?

Second solution - create my send function anywhere (just like a normal django function), and then create a 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))

And then in cron call : 0 0 * * * python /path/to/project/run.py newsletter.views daily_job()

Which method will work, or which is better ?

like image 972
crivateos Avatar asked Jul 08 '10 00:07

crivateos


3 Answers

i would suggest creating your functionality as django-management-command and run it via crontab

if your command is send_newsletter then simply

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

and you don't need to take care of setting the settings module in this case/

like image 95
Ashok Avatar answered Nov 12 '22 14:11

Ashok


Ashok's suggestion of running management commands via cron works well, but if you're looking for something a little more robust I'd look into a library like Kronos:

# app/cron.py

import kronos

@kronos.register('0 * * * *')
def task():
    pass
like image 11
Johannes Gorset Avatar answered Nov 12 '22 14:11

Johannes Gorset


I suggest to take a look at django-chronograph. Basically it does what you want in a simmilar way to other suggestions + it gives you a possbility to manage your cron jobs via admin panel. Cron jobs have to be implemented as django commands. You can then run all pending jobs by calling

python manage.py cron

which should be triggered by your cron.

like image 3
dzida Avatar answered Nov 12 '22 15:11

dzida