Comment planifier une tâche dans django périodiquement en utilisant django celery beat ?

voix
0

C'est ma première tentative avec le céleri, donc il y a évidemment quelques problèmes. Ici, je veux créer toutes Task Objectles minutes dans la base de données, donc j'ai utilisé django-celery-beat. Je veux utiliser une classe de programmateur personnalisé plus tard, donc pour cela j'ai utilisé le paquet django-celery-beat Mais je n'obtiens pas les résultats.

J'ai utilisé le formulaire django pour créer l'objet TaskModel et écrire une tâche dans tasks.py pour exécuter la vue toutes les minutes. Mais il lance cette erreur

Exception Type: EncodeError
Exception Value:    
Object of type timedelta is not JSON serializable

J'ai démarré celery dans une console avec la commande $ celery -A celery_demo beat -l info --scheduler django_celery_beat.schedulers:DatabaseScheduleret j'ai démarré le serveur django dans une autre console avec la commande py manage.py runserver

settings.py

CELERY_BROKER_URL = 'amqp://localhost'

CELERY_BEAT_SCHEDULE = {

        'task-first': {
        'task': 'scheduler.tasks.create_task',
        'schedule': timedelta(minutes=1)
       },

celery.py

from __future__ import absolute_import, unicode_literals

import os

from celery import Celery

# set the default Django settings module for the 'celery' program.
from django.conf import settings

os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'celery_demo.settings')

app = Celery('celery_demo')

# Using a string here means the worker doesn't have to serialize
# the configuration object to child processes.
# - namespace='CELERY' means all celery-related configuration keys
#   should have a `CELERY_` prefix.
app.config_from_object('django.conf:settings')

# Load task modules from all registered Django app configs.
app.autodiscover_tasks(settings.INSTALLED_APPS)


@app.task(bind=True)
def debug_task(self):
    print('Request: {0!r}'.format(self.request))

init.py

from __future__ import absolute_import, unicode_literals

# This will make sure the app is always imported when
# Django starts so that shared_task will use this app.
from .celery import app as celery_app

__all__ = ('celery_app',)

app/tasks.py

from celery.task import task
from django.shortcuts import redirect, render

from scheduler.models import Task

@task(name='create_task')
def add_task_celery(name=None, date=None, frequency=None):
    Task.objects.create(name=name, date=date, frequency=frequency)
    return redirect('list_tasks')

appp/views.py

def add_task(request):
    form = AddTaskForm()
    if request.method == 'POST':
        form = AddTaskForm(request.POST)
        if form.is_valid():
            name = form.cleaned_data.get('name')
            date = form.cleaned_data.get('date')
            freq = form.cleaned_data.get('frequency')

            add_task_celery.delay(name,date,freq)
    return render(request, 'add_task.html', {'form': form})

modèles

id=pre-6
Créé 01/06/2020 à 16:04
source utilisateur
Dans d'autres langues...                            


1 réponses

voix
0

Le problème se situe au niveau du troisième paramètre de la définition de la tâche, qui est freqet est de type timedelta. https://docs.djangoproject.com/en/3.0/ref/models/fields/#durationfield

Ceci doit être sérialisé avant de passer à la tâche. une façon simple serait.

1) vous pouvez sérialiser explicitement ce champ et le passer, dans la tâche à nouveau le convertir en objet timedelta.

2) une autre chose que vous pouvez essayer est de passer le sérialiseur dans les paramètres explicitement.

add_task_celery.delay(name,date,freq, serializer='json')

3) vous pouvez également définir une valeur pour le paramètre CELERY_TASK_SERIALIZER = 'json' (la valeur par défaut est cornichon)

Créé 04/06/2020 à 07:59
source utilisateur

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more