Il n’est pas rare d’avoir besoin de créer des tâches asynchrones dans vos applications. Si ces tâches sont à déclencher suite à l’action d’un utilisateur (édition d’une page, …), vous pouvez utiliser delayed job.
Mais si cette tâche doit être exécutée à interval régulier dans le temps, utiliser delayed job n’est pas faisable. Et il vous faudra créer un cron.

Pour cela je vais vous parler de Whenever.
L’utilisation est simpliste. Vous définissez tous vos crons dans config/schedule.rb. Et whenever se charge de générer automatiquement votre crontab.

Voici par exemple le document whenever pour RefStats.

every 1.minute do
  rake "crawler:work > #{RAILS_ROOT}/../shared/log/crawler.log"
end

every 1.day, :at => '2 am' do
  rake "maintenance:daily > #{RAILS_ROOT}/../shared/log/maintenance.log"
end

Toutes les minutes, le crawler récupérant les positions est lancé. Il s’agit d’une tâche rake.
Tous les jours à 2h du matin, la tâche « maintenance:daily » est lancée.

Suite à cela, depuis la base de votre projet, entrez en ligne de commande :

whenever

Vous verrez alors la crontab générée par whenever. Uniquement affichée, par mise à jour.
Si vous désirez mettre celle-ci à jour, c’est cependant simple.

whenever –update-crontab ApplicationName

L’option ApplicationName doit être différente pour chacune de vos applications. Ainsi whenever ne modifie que la crontab relative à cette application.

Du coup dans votre processus de déploiement Capistrano, vous ajoutez une tâche pour whenever :

after "deploy:symlink", "deploy:update_crontab"
namespace :deploy do
    desc "Update the crontab file"
    task :update_crontab, :roles => :db do
        run "cd #{release_path} && whenever --update-crontab #{application}"
    end
end

Et votre crontab sera remise automatiquement à jour à chaque fois que vous déploierez votre application. Plus à se soucier de cela manuellement :)

Vous avez normalement déjà manipulé les commandes console de Django, accessibles via manage.py.
./manage.py runserver

Cependant il peut être utile, dans plus d’une application, d’avoir des méthodes console pour lesquelles vous désirez obtenir l’environnement web, mais en console.
Pour charger des données depuis un flux XML par exemple. Ou encore vider une base de données.
Ainsi, vous pourrez faire :

./manage.py votre_commande

Dans l’application de votre choix, et qui doit être présente dans le INSTALLED_APPS de settings.py, créez l’arborescence suivante :
- management
|- __init__.py
|- commands
|– __init__.py

Ainsi, vous aurez ceci :
- votre_application
|- management
|– __init__.py
|– commands
|— __init__.py

Puis créez un fichier, que vous nommerez comme votre nouvelle commande dans le dossier commands.
Par exemple export.py

Dans ce fichier, vous placerez le code suivant :
from django.core.management.base import NoArgsCommand
class Command(NoArgsCommand):
  help = "Message d'aide concernant votre commande"
  def handle_noargs(self, **options):
    # Le contenu de votre commande
    print("Hello World")

Si, maintenant, vous tapez dans une console :

./manage.py export

Et le code présent dans votre méthode handle_noargs() sera exécuté :)

 
Fork me on GitHub