Using crontab with django [duplicate]

与世无争的帅哥 提交于 2019-12-29 04:01:27

问题


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

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 ?


回答1:


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/




回答2:


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



回答3:


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.




回答4:


I'd recommend option 3: use the jobs system in django-extensions. The relevant extension commands are:

  • create_jobs – Creates a Django jobs command directory structure for the given app name in the current directory. This is part of the impressive jobs system.
  • runjob – run a single maintenance job. Part of the jobs system.
  • runjobs – runs scheduled maintenance jobs. Specify hourly, daily, weekly, monthly. Part of the jobs system.

This lets you manage all the job handling inside of Django, so you don't have to keep messing with the crontab.




回答5:


I have written a few command-line applications using a method similar to your first option. I prefer to do it this way as opposed to using the DJANGO_SETTINGS_MODULE environment variable because it feels more like a regular Python program (to me).

You should also note that you do not have to put your module in the same directory as your settings.py; you can use the absolute Python path of your settings module:

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

PEP 8 discourages relative imports anyway.

I always install my Django applications in site-packages (/usr/lib64/python2.6/site-packages on Gentoo) so I don't have to worry about setting PYTHONPATH from my crontabs, but I don't believe that is a widely practiced method. I also like to use setuptools Automatic Script Creation so that my console scripts get put wherever they should be (/usr/bin, for example) and are named appropriately automatically. Your first option also facilitates this.




回答6:


There is also django-cron. It is very simple to use, there is nothing else to install or set-up.

However, I am not sure about how it really works... I mean that I don't know how the jobs are run and if they are run at all when nobody makes a request to the site. But you can try-out !




回答7:


Option 1 works for me. I normally have the script cd to the project directory and then do "python ./script_name.py" so that there are no mysterious path problems ... lazy, but it works consistently.



来源:https://stackoverflow.com/questions/3200001/using-crontab-with-django

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!