Tareas programadas en Django

En la última entrada relacionada con Django describía una desafortunada forma de acceder a lo que sería una tarea programada o cron con wget/links. Horrible, como bien comentaba el amigo Juanjo, así que vamos a intentar arreglarlo de alguna forma.

Leyendo e intentando no caer en lo simple, sino en lo correcto, me encuentro con los Custom Django-Admin Commands que, además de ser lo que buscaba, son oficiales y tienen una excelente documentación. Se trata de crear nuevos parámetros asociados a manage.py de forma que los podamos ejecutar directamente en consola:

(env)$ ./manage.py make_me_a_sandwich
Bread, Cheese, Jam... done!

¡Tampoco tenemos que abusar!. Es muy sencillo de implementar, tan solo requiere una nueva carpeta en vuestro proyecto. La estructura es tal que así:

proyecto/
|- management/
   |- __init__.py
   |- commands/
      |- __init__.py
      |- make_me_a_sandwich.py

Obviamente, lo nuevo pasa por la carpeta management y todo lo que hay en su interior. Y para que el ejemplo sea más completo, el código para hacer el sandwich sería el siguiente (make_me_a_sandwich.py):

from optparse import make_option
from django.core.management.base import BaseCommand, CommandError

# Class MUST be named 'Command'
class Command(BaseCommand):

    # Displayed from 'manage.py help mycommand'
    help = "That's Your help message"

    # make_option requires options in optparse format
    option_list = BaseCommand.option_list  + (
                        make_option('--myoption', action='store',
                            dest='myoption',
                            default='default',
                            help='Option help message'),
                  )

    def handle(self, *app_labels, **options):
        """
        app_labels - app labels (eg. myapp in "manage.py reset myapp")
        options - configurable command line options
        """

        # Return a success message to display to the user on success
        # or raise a CommandError as a failure condition
        if options['myoption'] == 'default':
            return 'Bread, Cheese, Jam... done!'

        raise CommandError('Only the default is supported')

De este modo ya podríamos ejecutar a cualquier hora el cron y tener el sandwich calentito al llegar a casa. Ojo si trabajamos con entornos virtuales, porque a la hora de crear la tarea programada debemos tenerlo en cuenta:

55   17   *   *   *   cd /proyecto/ ; . env/bin/activate ; ./src/manage.py make_me_a_sandwich

Creo que no me dejo nada en el tintero pero por si acaso ahí están los comentarios.

django code

About the author

Óscar
has doubledaddy super powers, father of Hugo and Nico, husband of Marta, *nix user, Djangonaut and open source passionate.