【问题标题】:Celery (4.2): how to get task id for current task芹菜(4.2):如何获取当前任务的任务ID
【发布时间】:2018-08-28 01:15:11
【问题描述】:

目标

出于闹钟的目的,我试图“获取”由UserSetAlarmForm 中创建的特定Alarm

从同一主题的其他答案(Q1Q2Q3)中,我正在尝试这条线:objx = Alarm.objects.get(id=run_alarm.request.id)。也许,我遗漏了一些明显的东西,或者 Celery 的版本已经更新?

错误

[ERROR/ForkPoolWorker-2] raised unexpected: DoesNotExist('Alarm matching query does not exist')

代码

Models.py

class Alarm(models.Model):
    """ Model representing each Alarm """
    id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)

Views.py

class AlarmCreateView(LoginRequiredMixin, CreateView):
    """ CreateView for User to create the Alarm object """
    model = Alarm
    form_class = SetAlarmForm
    template_name = 'weather_alarm/set_alarm.html'
    login_url = "/login/"

    def form_valid(self, form):
        self.create_alarm_object(self.request, form)
        run_alarm.delay()
        return HttpResponseRedirect(self.get_success_url())

Tasks.py

import time
from celery import Celery, shared_task, current_task
from datetime import datetime

from .models import Alarm


@shared_task
def run_alarm():
    """ Function to organise the steps for the alarm using Celery """
    objx = Alarm.objects.get(id=run_alarm.request.id)
    second_countdown = objx.get_alarm_length() # get the length of the alarm, in seconds
    time.sleep(second_countdown) # wait for the alarm time
    conditions_satisfied = objx.check_conditionals() # check if conditionals are satisfied
    if conditions_satisfied == True:                    # conditions are satified
        print("Ring ring!")
        return True
    else:                                               # conditions aren't satisfied
        print("I'm only sleeping!")
        return True

【问题讨论】:

    标签: python django celery


    【解决方案1】:

    解决此问题的最简单方法是使 alarmID 成为传递给您的任务的参数:

    Tasks.py

    @shared_task
    def run_alarm(alarmID):
        objx = Alarm.objects.get(id = alarmID)
    

    在视图中调用任务时需要传递此 ID:

    Views.py

    ...
    def form_valid(self, form):
        #making an assumption about what create_alarm_object returns here; you get the idea
        newAlarm = self.create_alarm_object(self.request, form)
        run_alarm.delay(newAlarm.id)
    

    请注意如何将参数传递给run_alarm,方法是在此处将其传递给delay。延伸阅读:http://docs.celeryproject.org/en/latest/userguide/calling.html#example

    您遇到错误的原因是request.id 将指向正在运行的单个异步 celery 任务的任务 ID,而不是警报对象的 ID。延伸阅读:http://docs.celeryproject.org/en/latest/userguide/tasks.html?highlight=request#task-request

    【讨论】:

    • 感谢您提供详细和参考的反馈。我按照建议尝试并得到:AttributeError: 'NoneType' object has no attribute 'id',异常位置为run_alarm.delay(newAlarm.id)
    • 您的 create_alarm_object 方法未包含在您的原始问题中,但我的示例是在假设此方法将返回它创建的警报对象的情况下编写的。看起来它目前正在返回None。您需要更新该方法以返回新创建的对象或其 ID,然后将该 ID 用作提供给 delay 调用的参数。
    猜你喜欢
    • 1970-01-01
    • 2019-08-06
    • 2015-09-28
    • 2021-01-02
    • 1970-01-01
    • 2011-03-19
    • 2019-12-09
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多