Джанго - настроить запланированное задание? - PullRequest
472 голосов
/ 21 февраля 2009

Я работал над веб-приложением с использованием Django, и мне любопытно, есть ли способ запланировать периодическое выполнение задания.

По сути, я просто хочу пробежаться по базе данных и производить некоторые вычисления / обновления на регулярной основе автоматически, но, похоже, не могу найти никакой документации по этому вопросу.

Кто-нибудь знает, как это настроить?

Чтобы уточнить: я знаю, что могу настроить работу cron, чтобы сделать это, но мне любопытно, есть ли какая-то функция в Django, которая обеспечивает эту функцию. Мне бы хотелось, чтобы люди могли самостоятельно развертывать это приложение, не прибегая к настройке (желательно к нулю).

Я подумал о том, чтобы инициировать эти действия «задним числом», просто проверив, нужно ли было выполнять задание с момента последней отправки запроса на сайт, но я надеюсь, что что-то будет чище.

Ответы [ 23 ]

0 голосов
/ 20 февраля 2019

Простой способ - написать собственную команду оболочки, см. Документация Django и выполнить ее с помощью cronjob в linux. Однако я очень рекомендую использовать брокера сообщений, как RabbitMQ в сочетании с сельдереем. Может быть, вы можете взглянуть на этот учебник

0 голосов
/ 25 января 2019

Для простых докеризованных проектов я не смог найти ни одного подходящего ответа.

Итак, я написал очень скромное решение без необходимости использования внешних библиотек или триггеров, которое работает само по себе. Не требуется внешний os-cron, он должен работать в любой среде.

Работает путем добавления промежуточного программного обеспечения: 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',
    ...
]
0 голосов
/ 22 мая 2018

Если вы хотите что-то более надежное , чем Сельдерей , попробуйте TaskHawk , который построен поверх AWS SQS / SNS .

См .: http://taskhawk.readthedocs.io

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...