Ustawiłeś zaplanowaną pracę?

Pracowałem nad aplikacją internetową używającą Django i jestem ciekaw, czy istnieje sposób na zaplanowanie pracy, która będzie uruchamiana okresowo.

Zasadniczo chcę po prostu uruchomić bazę danych i wykonać pewne obliczenia/aktualizacje automatycznie, regularnie, ale wydaje się, że nie mogę znaleźć żadnej dokumentacji na ten temat.

Czy ktoś wie jak to ustawić?

Dla wyjaśnienia: wiem, że mogę ustawić cron zadanie, aby to zrobić, ale jestem ciekaw, czy jest jakaś funkcja w Django to zapewnia tę funkcjonalność. Chciałbym, aby ludzie mogli samodzielnie wdrożyć tę aplikację bez konieczności robienia dużej config (najlepiej zero).

Rozważałem wywołanie tych działań "wstecz", po prostu sprawdzając, czy zadanie powinno być uruchomione od czasu ostatniego wysłania żądania na stronę, ale liczę na coś nieco czystszego.

Author: Suncatcher, 2009-02-21

24 answers

Jednym z rozwiązań, które zastosowałem, jest zrobienie tego:

1) Utwórz własne polecenie zarządzania , np.

python manage.py my_cool_command

2) Użyj cron (w Linuksie) lub at (W Windows), aby uruchomić moje polecenie w wymaganym czasie.

Jest to proste rozwiązanie, które nie wymaga instalowania ciężkiego stosu AMQP. Jednak istnieją miłe zalety korzystania z czegoś takiego jak seler, wymienione w innych odpowiedziach. W szczególności z selerem dobrze jest nie rozprzestrzeniać logiki aplikacji w plikach crontab. Jednak rozwiązanie cron działa całkiem nieźle w przypadku małych i średnich aplikacji i gdzie nie chcesz wielu zewnętrznych zależności.

EDIT:

W późniejszej wersji systemu windows polecenie at jest przestarzałe Dla Windows 8, Server 2012 i nowszych. Możesz użyć schtasks.exe do tego samego użytku.

**** UPDATE **** To nowy link z django doc do pisania niestandardowego polecenia zarządzania

 378
Author: Brian Neal,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-08-05 06:15:32

Selery jest rozproszoną kolejką zadań, zbudowaną na AMQP (RabbitMQ). Obsługuje również zadania okresowe w sposób podobny do crona(Zobacz zadania okresowe ). W zależności od aplikacji, może warto rzucić okiem.

Selery jest dość łatwy do skonfigurowania za pomocą django (docs), a okresowe zadania będą faktycznie pomijać pominięte zadania w przypadku przestoju. Seler posiada również wbudowane mechanizmy retry, w przypadku niepowodzenia zadania.

 157
Author: dln,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-02-06 00:58:01

Mamy open-source to, co myślę, że jest strukturyzowaną aplikacją. To rozwiązanie Briana również nawiązuje. Chcielibyśmy każdą / wszystkie opinie!

Https://github.com/tivix/django-cron

Pochodzi z jednego polecenia zarządzania:

./manage.py runcrons
To wystarczy. Każdy cron jest modelowany jako klasa (więc jego wszystkie OO), a każdy cron działa z inną częstotliwością i upewniamy się, że ten sam typ cron nie działa równolegle (w przypadku, gdy cron sam zajmuje więcej czasu niż ich częstotliwość!)
 52
Author: chachra,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2020-01-26 10:54:51

Jeśli używasz standardowego systemu operacyjnego POSIX, używasz cron .

Jeśli używasz Windows, używasz at .

Napisz polecenie zarządzania Django do

  1. Dowiedz się, na jakiej platformie są.

  2. Wykonaj odpowiednie polecenie " AT " dla swoich użytkowników, lub zaktualizuj plik crontab dla swoich użytkowników.

 38
Author: S.Lott,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-09-11 00:04:44

Ciekawy nowy pluggable Django app: django-chronograph

Musisz dodać tylko jeden wpis crona, który działa jak timer, i masz bardzo ładny interfejs admina Django do uruchamiania skryptów.

 23
Author: Van Gale,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-10-03 13:31:40

Spójrz na Django Poor Man ' s Cron, który jest aplikacją Django, która wykorzystuje spamboty, roboty indeksujące wyszukiwarki i podobne do uruchamiania zaplanowanych zadań w mniej więcej regularnych odstępach

Zobacz: http://code.google.com/p/django-poormanscron/

 16
Author: user41767,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-02-21 20:29:47

Miałem dokładnie ten sam wymóg jakiś czas temu, i skończyło się rozwiązując go za pomocą APScheduler (Instrukcja obsługi )

Sprawia, że planowanie zadań jest bardzo proste i utrzymuje je niezależne od wykonywania kodu opartego na żądaniach. Poniżej przedstawiamy prosty przykład.

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
Mam nadzieję, że to komuś pomoże!
 11
Author: PhoenixDev,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2020-01-08 17:29:06

Sugestia Briana Neala dotycząca uruchamiania poleceń zarządzania przez cron działa dobrze, ale jeśli szukasz czegoś bardziej solidnego (ale nie tak rozbudowanego jak selery), zajrzyj do biblioteki typu Kronos :

# app/cron.py

import kronos

@kronos.register('0 * * * *')
def task():
    pass
 10
Author: Johannes Gorset,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-12-26 00:23:52

RabbitMQ i selery mają więcej funkcji i możliwości obsługi zadań niż Cron. Jeśli niepowodzenie zadania nie jest problemem i uważasz, że poradzisz sobie z uszkodzonymi zadaniami w następnym wywołaniu, Cron jest wystarczający.

Selery & AMQP pozwoli Ci obsłużyć zepsute zadanie i zostanie ono ponownie wykonane przez innego pracownika (pracownicy selery słuchają następnego zadania do pracy), dopóki nie zostanie osiągnięty atrybut max_retries zadania. Możesz nawet wywoływać zadania w przypadku awarii, takie jak rejestrowanie awarii lub wysyłanie wiadomości e-mail do administratora po osiągnięciu max_retries.

I możesz dystrybuować Serwery selery i AMQP, gdy potrzebujesz skalować swoją aplikację.

 9
Author: Ravi Kumar,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-04-05 23:17:57

Osobiście używam crona, ale Jobs Scheduling części django-extensions wygląda interesująco.

 8
Author: Van Gale,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-09-05 15:08:39

Chociaż nie jest częścią Django, Airflow jest nowszym projektem (stan na 2016), który jest przydatny do zarządzania zadaniami.

Airflow to system automatyzacji przepływu pracy i planowania, który może być używany do tworzenia i zarządzania potokami danych. Interfejs internetowy zapewnia programistom szereg opcji zarządzania i przeglądania tych potoków.

Airflow jest napisany w Pythonie i jest zbudowany przy użyciu Flask.

Airflow został stworzony przez Maxime Beauchemin w Airbnb I open source wiosną 2015 roku. Dołączył do programu inkubacji Apache Software Foundation zimą 2016 roku. Oto strona projektu Git i kilka dodatkowych informacji .

 7
Author: Alexander,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-07-19 20:49:43

Umieść następujące na górze swojej cron.py plik:

#!/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
 6
Author: Matt McCormick,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-01-07 23:26:10

Właśnie pomyślałem o tym dość prostym rozwiązaniu:

  1. Zdefiniuj funkcję widoku do_work(req, param) tak jak w przypadku każdego innego widoku, z mapowaniem URL, zwracaniem HttpResponse i tak dalej.
  2. Skonfiguruj zadanie cron z preferencjami czasu (lub używając zadań AT lub zaplanowanych w systemie Windows), które uruchamia curl http://localhost/your/mapped/url?param = wartość.

Możesz dodawać parametry, ale po prostu dodawać parametry do adresu URL.

Powiedz mi co myślicie.

[Update] używam teraz komendy runjob z django-extensions zamiast curl.

Mój cron wygląda mniej więcej tak:

@hourly python /path/to/project/manage.py runjobs hourly

... i tak dalej dla dziennych, miesięcznych itp". Możesz również skonfigurować go tak, aby uruchamiał określone zadanie.

Uważam, że jest łatwiejszy w zarządzaniu i czystszy. Nie wymaga mapowania adresu URL do widoku. Po prostu określ swoją klasę pracy i crontab i jesteś gotowy.
 6
Author: Michael,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-01-25 21:15:07

Django APScheduler Dla zadań Schedulera. Advanced Python Scheduler (apscheduler) to biblioteka Pythona, która umożliwia zaplanowanie późniejszego wykonania kodu Pythona, tylko raz lub okresowo. Możesz dodawać nowe zadania lub usuwać stare w locie, jak chcesz.

Uwaga: jestem autorem tej biblioteki

Zainstaluj APScheduler

pip install apscheduler

Zobacz funkcję pliku do wywołania

Nazwa pliku: scheduler_jobs.py

def FirstCronTest():
    print("")
    print("I am executed..!")

Konfiguracja scheduler

Make execute.py plik i dodaj poniższe kody

from apscheduler.schedulers.background import BackgroundScheduler
scheduler = BackgroundScheduler()

Twoje funkcje pisane tutaj funkcje scheduler są zapisywane w scheduler_jobs

import scheduler_jobs 

scheduler.add_job(scheduler_jobs.FirstCronTest, 'interval', seconds=10)
scheduler.start()

Połącz plik do wykonania

Teraz dodaj poniższą linię na dole pliku Url

import execute
 5
Author: Chandan Sharma,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-09-19 22:10:39

Po części kodu mogę napisać wszystko tak jak mój 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)
#######################################

Od http://www.cotellese.net/2007/09/27/running-external-scripts-against-django-models/

 4
Author: xiaohei,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-05-17 03:09:13

Zdecydowanie powinieneś sprawdzić django-q! Nie wymaga dodatkowej konfiguracji i ma prawdopodobnie wszystko, co potrzebne do obsługi wszelkich problemów produkcyjnych w projektach komercyjnych.

Jest aktywnie rozwijany i bardzo dobrze integruje się z django, django ORM, mongo, redis. Oto moja konfiguracja:
# 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,
},
}
 4
Author: saran3h,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-08-04 05:50:24

Miałem dzisiaj coś podobnego z Twoim problemem.

Nie chciałem, aby obsługiwał go serwer trhough cron (a większość libów to w końcu tylko pomocnicy crona).

Więc stworzyłem moduł planowania i dołączyłem go do init .

Nie jest to najlepsze podejście, ale pomaga mi mieć cały kod w jednym miejscu i z jego wykonaniem związanym z główną aplikacją.

 2
Author: Fabricio Buzeto,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-09-02 18:41:33

Tak, powyższa metoda jest świetna. Próbowałem kilku z nich. W końcu znalazłem taką metodę:

    from threading import Timer

    def sync():

        do something...

        sync_timer = Timer(self.interval, sync, ())
        sync_timer.start()

Podobnie jak rekurencyjne .

Ok, mam nadzieję, że ta metoda może spełnić twoje wymagania. :)

 2
Author: Ni Xiaoni,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-03-26 01:04:36

Bardziej nowoczesnym rozwiązaniem (w porównaniu do selera) jest Django Q: https://django-q.readthedocs.io/en/latest/index.html

Ma świetną dokumentację i jest łatwy do grok. Brak wsparcia dla systemu Windows, ponieważ system Windows nie obsługuje rozwidlania procesów. Ale działa to dobrze, jeśli tworzysz środowisko programistyczne przy użyciu podsystemu Windows for Linux.

 2
Author: devdrc,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-11-11 16:38:15

Używam selera do tworzenia moich periodycznych zadań. Najpierw musisz zainstalować go w następujący sposób:

pip install django-celery

Nie zapomnij zarejestrować django-celery w ustawieniach, a potem możesz zrobić coś takiego:

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
 1
Author: David Felipe Camargo Polo,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-08-31 22:23:38

Nie jestem pewien, czy będzie to przydatne dla kogokolwiek, ponieważ musiałem zapewnić innym użytkownikom systemu zaplanować zadania, nie dając im dostępu do rzeczywistego Harmonogramu zadań serwera (windows), stworzyłem tę aplikację wielokrotnego użytku.

Należy pamiętać, że użytkownicy mają dostęp do jednego folderu udostępnionego na serwerze, w którym mogą utworzyć wymagane polecenie / zadanie/.plik bat. To zadanie można następnie zaplanować za pomocą tej aplikacji.

Nazwa aplikacji to Django_Windows_Scheduler

Zrzut ekranu: Tutaj wpisz opis obrazka

 1
Author: just10minutes,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-01-11 19:34:28

Jeśli chcesz czegoś więcej wiarygodnego niż selera , wypróbuj TaskHawk , który jest zbudowany na bazie AWS SQS/SNS .

Zobacz: http://taskhawk.readthedocs.io

 0
Author: Sri,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-05-21 23:53:52

Dla prostych dockerized projektów, tak naprawdę nie widziałem żadnej istniejącej odpowiedzi pasuje.

Więc napisałem bardzo proste rozwiązanie bez potrzeby zewnętrznych bibliotek lub wyzwalaczy, które działa samodzielnie. Nie jest potrzebny zewnętrzny os-cron, powinien działać w każdym środowisku.

Działa poprzez dodanie 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',
    ...
]
 0
Author: yspreen,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-01-25 12:13:05

Prostym sposobem jest napisanie niestandardowego polecenia powłoki Patrz Dokumentacja Django i wykonanie go przy użyciu cronjob na Linuksie. Jednak gorąco polecam korzystanie z brokera wiadomości, takiego jak RabbitMQ w połączeniu z selerem. Może rzucisz okiem na this Tutorial

 0
Author: Hamfri,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-02-20 10:21:02