405๐
One solution that I have employed is to do this:
1) Create a custom management command, e.g.
python manage.py my_cool_command
2) Use cron
(on Linux) or at
(on Windows) to run my command at the required times.
This is a simple solution that doesnโt require installing a heavy AMQP stack. However there are nice advantages to using something like Celery, mentioned in the other answers. In particular, with Celery it is nice to not have to spread your application logic out into crontab files. However the cron solution works quite nicely for a small to medium sized application and where you donโt want a lot of external dependencies.
EDIT:
In later version of windows the at
command is deprecated for Windows 8, Server 2012 and above. You can use schtasks.exe
for same use.
**** UPDATE ****
This the new link of django doc for writing the custom management command
172๐
Celery is a distributed task queue, built on AMQP (RabbitMQ). It also handles periodic tasks in a cron-like fashion (see periodic tasks). Depending on your app, it might be worth a gander.
Celery is pretty easy to set up with django (docs), and periodic tasks will actually skip missed tasks in case of a downtime. Celery also has built-in retry mechanisms, in case a task fails.
- [Django]-How to format time in django-rest-framework's serializer?
- [Django]-Suddenly when running tests I get "TypeError: 'NoneType' object is not iterable
- [Django]-Django migration fails with "__fake__.DoesNotExist: Permission matching query does not exist."
55๐
Weโve open-sourced what I think is a structured app. that Brianโs solution above alludes too. We would love any / all feedback!
https://github.com/tivix/django-cron
It comes with one management command:
./manage.py runcrons
That does the job. Each cron is modeled as a class (so its all OO) and each cron runs at a different frequency and we make sure the same cron type doesnโt run in parallel (in case crons themselves take longer time to run than their frequency!)
- [Django]-"<Message: title>" needs to have a value for field "id" before this many-to-many relationship can be used.
- [Django]-Pytest.mark.parametrize with django.test.SimpleTestCase
- [Django]-How to server HTTP/2 Protocol with django
37๐
If youโre using a standard POSIX OS, you use cron.
If youโre using Windows, you use at.
Write a Django management command to
-
Figure out what platform theyโre on.
-
Either execute the appropriate โATโ command for your users, or update the crontab for your users.
- [Django]-What is actually assertEquals in Python?
- [Django]-How to use regex in django query
- [Django]-"<Message: title>" needs to have a value for field "id" before this many-to-many relationship can be used.
23๐
Interesting new pluggable Django app: django-chronograph
You only have to add one cron entry which acts as a timer, and you have a very nice Django admin interface into the scripts to run.
- [Django]-How to obtain and/or save the queryset criteria to the DB?
- [Django]-How can I upgrade specific packages using pip and a requirements file?
- [Django]-Resource temporarily unavailable using uwsgi + nginx
16๐
Look at Django Poor Manโs Cron which is a Django app that makes use of spambots, search engine indexing robots and alike to run scheduled tasks in approximately regular intervals
- [Django]-Django custom management commands: AttributeError: 'module' object has no attribute 'Command'
- [Django]-How to go from django image field to PIL image and back?
- [Django]-Django character set with MySQL weirdness
15๐
I had exactly the same requirement a while ago, and ended up solving it using APScheduler (User Guide)
It makes scheduling jobs super simple, and keeps it independent for from request-based execution of some code. Following is a simple example.
from apscheduler.schedulers.background import BackgroundScheduler
scheduler = BackgroundScheduler()
job = None
def tick():
print('One tick!')\
def start_job():
global job
job = scheduler.add_job(tick, 'interval', seconds=3600)
try:
scheduler.start()
except:
pass
Hope this helps somebody!
- [Django]-Disable session creation in Django
- [Django]-Do django db_index migrations run concurrently?
- [Django]-Group by Foreign Key and show related items โ Django
11๐
Brian Nealโs suggestion of running management commands via cron works well, but if youโre looking for something a little more robust (yet not as elaborate as Celery) Iโd look into a library like Kronos:
# app/cron.py
import kronos
@kronos.register('0 * * * *')
def task():
pass
- [Django]-Django rest framework lookup_field through OneToOneField
- [Django]-Django QuerySet order
- [Django]-Is there a list of Pytz Timezones?
11๐
Django APScheduler for Scheduler Jobs. Advanced Python Scheduler (APScheduler) is a Python library that lets you schedule your Python code to be executed later, either just once or periodically. You can add new jobs or remove old ones on the fly as you please.
note: Iโm the author of this library
Install APScheduler
pip install apscheduler
View file function to call
file name: scheduler_jobs.py
def FirstCronTest():
print("")
print("I am executed..!")
Configuring the scheduler
make execute.py file and add the below codes
from apscheduler.schedulers.background import BackgroundScheduler
scheduler = BackgroundScheduler()
Your written functions Here, the scheduler functions are written in scheduler_jobs
import scheduler_jobs
scheduler.add_job(scheduler_jobs.FirstCronTest, 'interval', seconds=10)
scheduler.start()
Link the File for Execution
Now, add the below line in the bottom of Url file
import execute
- You can check the full code by executing
[Click here]
https://github.com/devchandansh/django-apscheduler
- [Django]-How do I get the class of a object within a Django template?
- [Django]-With DEBUG=False, how can I log django exceptions to a log file
- [Django]-How to produce a 303 Http Response in Django?
10๐
RabbitMQ and Celery have more features and task handling capabilities than Cron. If task failure isnโt an issue, and you think you will handle broken tasks in the next call, then Cron is sufficient.
Celery & AMQP will let you handle the broken task, and it will get executed again by another worker (Celery workers listen for the next task to work on), until the taskโs max_retries
attribute is reached. You can even invoke tasks on failure, like logging the failure, or sending an email to the admin once the max_retries
has been reached.
And you can distribute Celery and AMQP servers when you need to scale your application.
- [Django]-Django model CharField: max_length does not work?
- [Django]-Django Template Language: Using a for loop with else
- [Django]-Django: Use of DATE_FORMAT, DATETIME_FORMAT, TIME_FORMAT in settings.py?
8๐
I personally use cron, but the Jobs Scheduling parts of django-extensions looks interesting.
- [Django]-Referencing multiple submit buttons in django
- [Django]-How can I activate the unaccent extension on an already existing model
- [Django]-Django โ No module named _sqlite3
8๐
Although not part of Django, Airflow is a more recent project (as of 2016) that is useful for task management.
Airflow is a workflow automation and scheduling system that can be used to author and manage data pipelines. A web-based UI provides the developer with a range of options for managing and viewing these pipelines.
Airflow is written in Python and is built using Flask.
Airflow was created by Maxime Beauchemin at Airbnb and open sourced in the spring of 2015. It joined the Apache Software Foundationโs incubation program in the winter of 2016. Here is the Git project page and some addition background information.
- [Django]-Cross domain at axios
- [Django]-Macros in django templates
- [Django]-Itertools.groupby in a django template
6๐
Put the following at the top of your cron.py file:
#!/usr/bin/python
import os, sys
sys.path.append('/path/to/') # the parent directory of the project
sys.path.append('/path/to/project') # these lines only needed if not on path
os.environ['DJANGO_SETTINGS_MODULE'] = 'myproj.settings'
# imports and code below
- [Django]-How to use Django ImageField, and why use it at all?
- [Django]-Django gunicorn sock file not created by wsgi
- [Django]-Django py.test does not find settings module
6๐
I just thought about this rather simple solution:
- Define a view function do_work(req, param) like you would with any other view, with URL mapping, return a HttpResponse and so on.
- Set up a cron job with your timing preferences (or using AT or Scheduled Tasks in Windows) which runs curl http://localhost/your/mapped/url?param=value.
You can add parameters but just adding parameters to the URL.
Tell me what you guys think.
[Update] Iโm now using runjob command from django-extensions instead of curl.
My cron looks something like this:
@hourly python /path/to/project/manage.py runjobs hourly
โฆ and so on for daily, monthly, etcโ. You can also set it up to run a specific job.
I find it more managable and a cleaner. Doesnโt require mapping a URL to a view. Just define your job class and crontab and youโre set.
- [Django]-Detect mobile, tablet or Desktop on Django
- [Django]-Complete django DB reset
- [Django]-Celery. Decrease number of processes
4๐
after the part of code,I can write anything just like my views.py ๐
#######################################
import os,sys
sys.path.append('/home/administrator/development/store')
os.environ['DJANGO_SETTINGS_MODULE']='store.settings'
from django.core.management impor setup_environ
from store import settings
setup_environ(settings)
#######################################
from
http://www.cotellese.net/2007/09/27/running-external-scripts-against-django-models/
- [Django]-How to specify an IP address with Django test client?
- [Django]-Django F() division โ How to avoid rounding off
- [Django]-Filtering dropdown values in django admin
4๐
You should definitely check out django-q!
It requires no additional configuration and has quite possibly everything needed to handle any production issues on commercial projects.
Itโs actively developed and integrates very well with django, django ORM, mongo, redis. Here is my configuration:
# django-q
# -------------------------------------------------------------------------
# See: http://django-q.readthedocs.io/en/latest/configure.html
Q_CLUSTER = {
# Match recommended settings from docs.
'name': 'DjangoORM',
'workers': 4,
'queue_limit': 50,
'bulk': 10,
'orm': 'default',
# Custom Settings
# ---------------
# Limit the amount of successful tasks saved to Django.
'save_limit': 10000,
# See https://github.com/Koed00/django-q/issues/110.
'catch_up': False,
# Number of seconds a worker can spend on a task before it's terminated.
'timeout': 60 * 5,
# Number of seconds a broker will wait for a cluster to finish a task before presenting it again. This needs to be
# longer than `timeout`, otherwise the same task will be processed multiple times.
'retry': 60 * 6,
# Whether to force all async() calls to be run with sync=True (making them synchronous).
'sync': False,
# Redirect worker exceptions directly to Sentry error reporter.
'error_reporter': {
'sentry': RAVEN_CONFIG,
},
}
- [Django]-Cannot set Django to work with smtp.gmail.com
- [Django]-Rendering a value as text instead of field inside a Django Form
- [Django]-What does error mean? : "Forbidden (Referer checking failed โ no Referer.):"
3๐
Yes, the method above is so great. And I tried some of them. At last, I found a method like this:
from threading import Timer
def sync():
do something...
sync_timer = Timer(self.interval, sync, ())
sync_timer.start()
Just like Recursive.
Ok, I hope this method can meet your requirement. ๐
- [Django]-Allowing RabbitMQ-Server Connections
- [Django]-Celery : Execute task after a specific time gap
- [Django]-Django error when installing Graphite โ settings.DATABASES is improperly configured. Please supply the ENGINE value
3๐
A more modern solution (compared to Celery) is Django Q:
https://django-q.readthedocs.io/en/latest/index.html
It has great documentation and is easy to grok. Windows support is lacking, because Windows does not support process forking. But it works fine if you create your dev environment using the Windows for Linux Subsystem.
- [Django]-Unittest Django: Mock external API, what is proper way?
- [Django]-How to change User representation in Django Admin when used as Foreign Key?
- [Django]-Do django db_index migrations run concurrently?
2๐
I had something similar with your problem today.
I didnโt wanted to have it handled by the server trhough cron (and most of the libs were just cron helpers in the end).
So iโve created a scheduling module and attached it to the init .
Itโs not the best approach, but it helps me to have all the code in a single place and with its execution related to the main app.
- [Django]-In django, how do I sort a model on a field and then get the last item?
- [Django]-How to format time in django-rest-framework's serializer?
- [Django]-Django apps aren't loaded yet when using asgi
1๐
I use celery to create my periodical tasks. First you need to install it as follows:
pip install django-celery
Donโt forget to register django-celery
in your settings and then you could do something like this:
from celery import task
from celery.decorators import periodic_task
from celery.task.schedules import crontab
from celery.utils.log import get_task_logger
@periodic_task(run_every=crontab(minute="0", hour="23"))
def do_every_midnight():
#your code
- [Django]-AccessDenied when calling the CreateMultipartUpload operation in Django using django-storages and boto3
- [Django]-Django middleware difference between process_request and process_view
- [Django]-Python Socket.IO client for sending broadcast messages to TornadIO2 server
1๐
I am not sure will this be useful for anyone, since I had to provide other users of the system to schedule the jobs, without giving them access to the actual server(windows) Task Scheduler, I created this reusable app.
Please note users have access to one shared folder on server where they can create required command/task/.bat file. This task then can be scheduled using this app.
App name is Django_Windows_Scheduler
- [Django]-How to reset Django admin password?
- [Django]-Alowing 'fuzzy' translations in django pages?
- [Django]-Handling race condition in model.save()
0๐
If you want something more reliable than Celery, try TaskHawk which is built on top of AWS SQS/SNS.
- [Django]-*_set attributes on Django Models
- [Django]-Are Django SECRET_KEY's per instance or per app?
- [Django]-What is actually assertEquals in Python?
0๐
For simple dockerized projects, I could not really see any existing answer fit.
So I wrote a very barebones solution without the need of external libraries or triggers, which runs on its own. No external os-cron needed, should work in every environment.
It works by adding a middleware: middleware.py
import threading
def should_run(name, seconds_interval):
from application.models import CronJob
from django.utils.timezone import now
try:
c = CronJob.objects.get(name=name)
except CronJob.DoesNotExist:
CronJob(name=name, last_ran=now()).save()
return True
if (now() - c.last_ran).total_seconds() >= seconds_interval:
c.last_ran = now()
c.save()
return True
return False
class CronTask:
def __init__(self, name, seconds_interval, function):
self.name = name
self.seconds_interval = seconds_interval
self.function = function
def cron_worker(*_):
if not should_run("main", 60):
return
# customize this part:
from application.models import Event
tasks = [
CronTask("events", 60 * 30, Event.clean_stale_objects),
# ...
]
for task in tasks:
if should_run(task.name, task.seconds_interval):
task.function()
def cron_middleware(get_response):
def middleware(request):
response = get_response(request)
threading.Thread(target=cron_worker).start()
return response
return middleware
models/cron.py
:
from django.db import models
class CronJob(models.Model):
name = models.CharField(max_length=10, primary_key=True)
last_ran = models.DateTimeField()
settings.py
:
MIDDLEWARE = [
...
'application.middleware.cron_middleware',
...
]
- [Django]-ImportError: Failed to import test module:
- [Django]-Form with CheckboxSelectMultiple doesn't validate
- [Django]-Django Framework โ Is there a shutdown event that can be subscribed to?
0๐
Simple way is to write a custom shell command see Django Documentation and execute it using a cronjob on linux. However i would highly recommend using a message broker like RabbitMQ coupled with celery. Maybe you can have a look at
this Tutorial
- [Django]-Django get objects not referenced by foreign key
- [Django]-How to force application version on AWS Elastic Beanstalk
- [Django]-How to save pillow image object to Django ImageField?
0๐
One alternative is to use Rocketry:
from rocketry import Rocketry
from rocketry.conds import daily, after_success
app = Rocketry()
@app.task(daily.at("10:00"))
def do_daily():
...
@app.task(after_success(do_daily))
def do_after_another():
...
if __name__ == "__main__":
app.run()
It also supports custom conditions:
from pathlib import Path
@app.cond()
def file_exists(file):
return Path(file).exists()
@app.task(daily & file_exists("myfile.csv"))
def do_custom():
...
And it also supports Cron:
from rocketry.conds import cron
@app.task(cron('*/2 12-18 * Oct Fri'))
def do_cron():
...
It can be integrated quite nicely with FastAPI and I think it could be integrated with Django as well as Rocketry is essentially just a sophisticated loop that can spawn, async tasks, threads and processes.
Disclaimer: Iโm the author.
- [Django]-Add inline model to django admin site
- [Django]-Django โ Website Home Page
- [Django]-Do django db_index migrations run concurrently?
0๐
Another option, similar to Brian Nealโs answer it to use RunScripts
Then you donโt need to set up commands. This has the advantage of more flexible or cleaner folder structures.
This file must implement a run() function. This is what gets called when you run the script. You can import any models or other parts of your django project to use in these scripts.
And then, just
python manage.py runscript path.to.script
- [Django]-How to server HTTP/2 Protocol with django
- [Django]-Django urlsafe base64 decoding with decryption
- [Django]-Django filter JSONField list of dicts