Python 从Django代码调用芹菜任务的正确方法?

Python 从Django代码调用芹菜任务的正确方法?,python,django,celery,djcelery,Python,Django,Celery,Djcelery,我有一个注册表单,在提交时,我想通过一些外部API执行一些数据验证,然后最终提交到另一个API。我希望异步执行此操作,这样提交者就不会等待表单提交10秒 到目前为止,这是我的代码——它可以工作,但是如果在任务中抛出异常,用户将得到500个错误(具体的异常是,有时我使用的第三方API超时)。我的印象是,如果任务是异步执行的(注意@task decorator并使用delay调用任务),那么不管函数中发生了什么,都应该加载成功页面 views.py tasks.py 使用try/except子句包装

我有一个注册表单,在提交时,我想通过一些外部API执行一些数据验证,然后最终提交到另一个API。我希望异步执行此操作,这样提交者就不会等待表单提交10秒

到目前为止,这是我的代码——它可以工作,但是如果在任务中抛出异常,用户将得到500个错误(具体的异常是,有时我使用的第三方API超时)。我的印象是,如果任务是异步执行的(注意@task decorator并使用delay调用任务),那么不管函数中发生了什么,都应该加载成功页面

views.py tasks.py 使用try/except子句包装prepare_和submit_数据的内容并记录错误是否是正确的解决方案?或者将函数的调用包装在寄存器中


谢谢。

如果任务是异步执行的,那么延迟调用是非阻塞的,它只是将任务放入消息队列,并立即继续执行视图的代码,这意味着无论任务成功还是失败,它都不会对视图的代码产生任何影响。本声明的例外情况如下:

  • 如果任务队列由于某种原因而失败,例如,您的消息队列无法访问,因此无法安排任务,在这种情况下,您在调用
    prepare\u和\u submit\u data.delay时会出现异常

  • 设置为
    True
    ,这意味着即使在显式请求异步执行任务时,它也将同步执行,这与定期调用阻塞函数相同(
    prepare_和_submit_data()

我打赌是在后一种情况下,您已经正确地编写了代码,但是上面提到的设置强制它同步执行。但要考虑的是,当您的视图返回响应时,几乎可以肯定您不会得到可用的异步任务的结果。因此,如果您打算在视图执行期间使用异步验证的结果,那么您不需要异步运行它,您从一开始就是在常规同步执行之后。但是,如果您以后才需要使用它,一种常见的技术是使用定期从客户端向单独的API端点发出的ajax请求,这应该检查您的任务是否完成了执行并返回结果

from myapp.tasks import prepare_and_submit_data

def register(request):
  form = SignupForm(request.POST or None)
  if form.is_valid():

    # Async function.
    prepare_and_submit_data.delay(form.cleaned_data)

    return render(request, 'success.html', {})
  return render(request, 'signup.html', {'form': form})
from celery.decorators import task

@task
def prepare_and_submit_data(data):
  # do some external API requests and modify data
  data = requests.post(BASE_URL, data=data).json()
  # ...