I’m new to Django and web frameworks in general. I have an app that is all set up and works perfectly fine on my localhost.
The program uses Twitter’s API to gather a bunch of tweets and displays them to the user. The only problem is I need my python program that gets the tweets to be run in the background every-so-often.
This is where using the schedule module would make sense, but once I start the local server it never runs the schedule functions. I tried reading up on cronjobs and just can’t seem to get it to work. How can I get Django to run a specific python file periodically?
2
Answers
I’ve encountered a similar situation and have had a lot of success with
django-apscheduler
. It is all self-contained – it runs with the Django server and jobs are tracked in the Django database, so you don’t have to configure any external cron jobs or anything to call a script.Below is a basic way to get up and running quickly, but the links at the end of this post have far more documentation and details as well as more advanced options.
Install with
pip install django-apscheduler
then add it to yourINSTALLED_APPS
:Once installed, make sure to run
makemigrations
andmigrate
on the database.Create a
scheduler
python package (a folder in your app directory namedscheduler
with a blank__init__.py
in it). Then, in there, create a file namedscheduler.py
, which should look something like this:In your apps.py file (create it if it doesn’t exist):
A word of caution: when using this with
DEBUG = True
in yoursettings.py
file, run the development server with the--noreload
flag set (i.e.python manage.py runserver localhost:8000 --noreload
), otherwise the scheduled tasks will start and run twice.Also,
django-apscheduler
does not allow you to pass any parameters to the functions that are scheduled to be run. It is a limitation, but I’ve never had a problem with it. You can load them from some external source, like the Django database, if you really need to.You can use all the standard Django libraries, packages and functions inside the apscheduler tasks (functions). For example, to query models, call external APIs, parse responses/data, etc. etc. It’s seamlessly integrated.
Some additional links:
https://medium.com/@mrgrantanderson/replacing-cron-and-running-background-tasks-in-django-using-apscheduler-and-django-apscheduler-d562646c062e
Another library you can use is django-q
Like
django-appscheduler
it can run and track jobs using the database Django is attached to. Or, it can use full-blown brokers like Reddis.That sounds like a scheduler. (Django-q also has a tasks feature, that can be triggered by events rather than being run on a schedule. The scheduler just sits on top of the task feature, and triggers tasks at a defined schedule.)
There’s three parts to this with django-q:
Install django-q
Configure it as an installed app in Django
settings.py
(add it to the install apps list):Then it needs it’s own configuration
settings.py
(this is a configuration to use the database as the broker rather than reddis or something external to Django.)You’ll then need to run migrations on the database to create the tables django-q uses:
(This will create a bunch of schedule and task related tables in the database. They can be viewed and manipulated through the Django admin panel.)
Define a task function
Then create a new file for the tasks you want to run:
Define a task schedule
We need to add into the database the schedule to run the tasks.
You don’t have to do this through the shell. You can do this in a module of python code, etc. But you probably only need to create the schedule once.
Run the cluster
Once that’s all done, you need to run the cluster that will process the schedule. Otherwise, without running the cluster, the schedule and tasks will never be processed. The call to qcluster is a blocking call. So normally you want to run it in a separate window or process from the Django server process.
When it runs you’ll see output like:
There’s also some example documentation that’s pretty useful if you want to see how to hook up tasks to reports or emails or signals etc.