Set up a scheduled job?

后端 未结 24 2532
爱一瞬间的悲伤
爱一瞬间的悲伤 2020-11-22 01:13

I\'ve been working on a web app using Django, and I\'m curious if there is a way to schedule a job to run periodically.

Basically I just want to run through the dat

24条回答
  •  栀梦
    栀梦 (楼主)
    2020-11-22 01:53

    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',
        ...
    ]
    

提交回复
热议问题