【译】Celery文档3:在Django中使用Celery

简介: 【译】Celery文档3:在Django中使用Celery

First steps with Django

Django3.1后默认支持Celery,不再需要安装额外的库。

Django项目布局大概是这样的:

- proj/
  - manage.py
  - proj/
    - __init__.py
    - settings.py
    - urls.py

想要添加celery,推荐在proj/proj目录下创建一个celery.py 模块,并定义Celery实例:

import os

from celery import Celery

# Set the default Django settings module for the 'celery' program.
# 设置环境变量,使得不必将设置模块传入celery。
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'proj.settings')

app = Celery('proj')

# 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', namespace='CELERY') # 使用Django的设置模块作为celery的配置源

# Load task modules from all registered Django apps.
app.autodiscover_tasks()


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

然后,您需要在 proj/proj/__init__.py模块中导入此应用程序。这确保了在 Django 启动时加载应用程序,以便 @shared_task 装饰器(稍后提到)将使用它:

proj/proj/__init__.py:

# 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',)

Django的配置文件可能包括:

settings.py

...

# Celery Configuration Options
CELERY_TIMEZONE = "Australia/Tasmania"
CELERY_TASK_TRACK_STARTED = True
CELERY_TASK_TIME_LIMIT = 30 * 60

接下来,通常在单独的 tasks.py 模块中定义所有任务,而 Celery实际上有一种方法可以自动发现这些模块:

app.autodiscover_tasks()

通过上面的一行,Celery 将按照 tasks.py 约定自动发现所有已安装应用程序中的任务:

- app1/
    - tasks.py
    - models.py
- app2/
    - tasks.py
    - models.py

这样,您就不必手动将各个模块添加到设置中 CELERY_IMPORTS 。


proj/proj/celery.py文件的最后定义了debug_task任务,该任务是一个转储自己的请求信息的任务。使用 Celery 3.1 中引入的bind=True选项来轻松使用当前任务实例。


使用@shared_task 装饰器

@shared_task装饰器允许您创建任务,而无需任何具体的app实例:

demoapp/tasks.py:

 Create your tasks here

from demoapp.models import Widget

from celery import shared_task


@shared_task
def add(x, y):
    return x + y


@shared_task
def mul(x, y):
    return x * y


@shared_task
def xsum(numbers):
    return sum(numbers)


@shared_task
def count_widgets():
    return Widget.objects.count()


@shared_task
def rename_widget(widget_id, name):
    w = Widget.objects.get(id=widget_id)
    w.name = name
    w.save()

Django示例的完整代码:https://github.com/celery/celery/tree/main/examples/django/

在数据库事务结束时触发任务

Django 的一个常见陷阱是立即触发任务,而不是等到数据库事务结束,这意味着 Celery 任务可能会在所有更改都持久化到数据库之前运行。例如:

# views.py
def create_user(request):
    # Note: simplified example, use a form to validate input
    user = User.objects.create(username=request.POST['username'])
    send_email.delay(user.pk)
    return HttpResponse('User created')

# task.py
@shared_task
def send_email(user_pk):
    user = User.objects.get(pk=user_pk)
    # send email ...

在这种情况下, send_email 任务可能在视图将事务提交到数据库之前启动,因此任务可能无法找到用户。

一个常见的解决方案是在事务提交后使用 Django 的 on_commit 钩子来触发任务:

- send_email.delay(user.pk)
+ transaction.on_commit(lambda: send_email.delay(user.pk))


由于这是一种常见的模式,Celery 5.4 为此引入了一个方便的快捷方式,使用 DjangoTask。 你可以使用delay_on_commit() 替代delay():

- send_email.delay(user.pk)
+ send_email.delay_on_commit(user.pk)


Extensions

django-celery-results 使用 Django ORM/Cache 作为结果后端

https://pypi.org/project/django-celery-results/

django-celery-beat - 具有管理界面的数据库支持的定期任务

启动工作进程

在生产环境中,你会希望在后台运行 worker 作为守护进程 - 参见 Daemonization - 但对于测试和开发来说,能够使用 celery worker manage 命令启动工作线程实例很有用.

celery -A proj worker -l INFO

相关文章
|
7月前
|
NoSQL 调度 Redis
33 Django高级 - celery
33 Django高级 - celery
28 0
|
15天前
|
程序员 API 网络架构
在django中处理文档和结构
【6月更文挑战第11天】该文介绍了如何使用Django REST框架和相关工具创建和记录API文档。并强调了文档在API开发中的重要性,并鼓励使用自动化工具确保文档的准确性和时效性。
21 1
在django中处理文档和结构
|
关系型数据库 MySQL 测试技术
django基于python智能在线考试阅卷系统(源码+系统+mysql数据库+Lw文档)
随着计算机多媒体技术的发展和网络的普及。采用当前流行的B/S模式以及3层架构的设计思想通过Python技术来开发此系统的目的是建立一个配合网络环境的基于python的学校对在线考试阅卷系统的平台,这样可以有效地解决基于python的在线考试阅卷系统混乱的局面。本文首先介绍了基于python的在线考试系统的发展背景与发展现状,然后遵循软件常规开发流程,首先针对系统选取适用的语言和开发平台,根据需求分析制定模块并设计数据库结构,再根据系统总体功能模块的设计绘制系统的功能模块图,流程图以及E-R图。然后,设计框架并根据设计的框架编写代码以实现系统的各个功能模块。最后,对初步完成的系统进行测试,主要是
425 0
|
数据采集 机器学习/深度学习 算法
基于python机器学习 Django的二手房交易预测及展示系统 完整代码+报告文档
基于python机器学习 Django的二手房交易预测及展示系统 完整代码+报告文档
591 0
基于python机器学习 Django的二手房交易预测及展示系统 完整代码+报告文档
|
JSON NoSQL Redis
Win11系统下使用Django+Celery实现异步任务队列以及定时(周期)任务(2020年最新攻略)
首先明确一点,celery4.1+的官方文档已经详细说明,该版本之后不需要引入依赖 django-celery 这个库了,直接用 celery 本身就可以了,就在去年年初的一篇文章[python3.7.2+Django2.0.4 使用django-celery遇到的那些坑](https://v3u.cn/a_id_54),中提到的一些bug,在今年早已不复存在,所以技术更新频率越来越快,本文详细阐述用新版Celery(4.4.2)来实现。
Win11系统下使用Django+Celery实现异步任务队列以及定时(周期)任务(2020年最新攻略)
|
监控 Python
Python编程:Django中使用Celery执行异步任务和定时任务
Python编程:Django中使用Celery执行异步任务和定时任务
194 0
|
Python
django celery 异步执行任务遇到的坑
django celery 异步执行任务遇到的坑
Django查看celery任务结果
异步任务执行的时候对于用户来说总是会出现再次尝试,第二次查看结果的时候如果能查到任务结果如何那就可以减少好多不必要的查询和重试。
|
Python NoSQL Redis
Django配置celery定时任务
安装celery 使用redis+celery的方式(使用的是阿里源,也可以选择不用) pip install -i https://mirrors.aliyun.com/pypi/simple/ -U "celery[redis]" 修改Django的settings配置文件 添加celery文件在app同级目录下添加一个文件夹,例:service_celery 在文件夹中添加celery.
|
Web App开发 安全 测试技术
Django 2.1.3文档
关于Django你需要知道的一切。 获得帮助 遇到麻烦?我们想帮忙! 尝试常见问题解答 - 它可以解答许多常见问题。 寻找具体信息?尝试索引,模块索引或详细目录。 在django-users邮件列表的档案中搜索信息,或 发布问题。
2274 0