简体   繁体   中英

How can I schedule a task at time from django frontend?

I'm programming an irrigation system with Django and I use Celery to handle asynchronous tasks.

In my application the user selects the days and hours that he wants to activate the irrigation, this is stored in the database and he can update them at any time.

I know I can schedule tasks like this, but I want to update the time.

from celery.task.schedules import crontab
from celery.decorators import periodic_task

@periodic_task(run_every=crontab(hour=7, minute=30, day_of_week="mon"))
def every_monday_morning():
    print("This runs every Monday morning at 7:30a.m.")

Another way is to use python-crontab

did something similar by having a runtime table listing what I wanted to run and when available to be selected from Django.

Periodic task itself was then scheduled to run every 30 seconds and check if anything requested in this table ready to be executed and called one of the workers.

Edit:as requested by Graham an example

The settings in Django to setup the beat:

CELERY_BEAT_SCHEDULE = {
    'Runtime': {
    'task': 'Runtime',
    'schedule': timedelta(seconds=15),
    },
}

The task calling the model defined in Django (irrigation_requests in this eg) that the user would be updating through the front end:

def Runtime():
    #get all from model in state requested
    irrigation_job=Irrigation_Requests.objects.filter(Status__in=['Requested'])

    # Process each requested if flag to do just one thing then you could just test irrigation_job exists      
    for job in irrigation_job:
        ....
        print ("This runs every when requested and depending on job parameters stored in your model can have further scope")

    #update requested this could be done in loop above
    irrigation_job.update(Status='Processed')

It finally dawned on me after I've seen Mark's answer . So I will do it using a code similar to this:

from celery.task.schedules import crontab
from celery.decorators import periodic_task

@periodic_task(run_every=crontab(minutes="*"))
def run_every_minute():
    now = datetime.datetime.now()
    tasks = TasksModel.objects.all()
    for task in Tasks:
        if task.is_now():
            fn = find_schedual_task(task.name)
            fn()

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM