对于这样的应用程序,最好使用Django Background Tasks
,
从 PyPI 安装:
pip install django-background-tasks
添加到 INSTALLED_APPS:
INSTALLED_APPS = (
# ...
'background_task',
# ...
)
迁移数据库:
python manage.py makemigrations background_task
python manage.py migrate
创建和注册任务
要注册任务,请使用背景装饰器:
from background_task import background
from django.contrib.auth.models import User
@background(schedule=60)
def notify_user(user_id):
# lookup user by id and send them a message
user = User.objects.get(pk=user_id)
user.email_user('Here is a notification', 'You have been notified')
这会将 notify_user 转换为后台任务函数。当您从常规代码中调用它时,它实际上会创建一个 Task 对象并将其存储在数据库中。然后,数据库包含有关稍后实际需要运行的函数的序列化信息。这确实限制了调用函数时可以传递的参数——它们都必须可序列化为 JSON。因此,为什么在上面的示例中传递的是 user_id 而不是 User 对象。
正常调用 notify_user 将安排原始函数在 60 秒后运行:
notify_user(user.id)
这是默认的调度时间(在装饰器中设置),但它可以被覆盖:
notify_user(user.id, schedule=90) # 90 seconds from now
notify_user(user.id, schedule=timedelta(minutes=20)) # 20 minutes from now
notify_user(user.id, schedule=timezone.now()) # at a specific time
您也可以立即在同步模式下运行原始功能:
notify_user.now(user.id) # launch a notify_user function and wait for it
notify_user = notify_user.now # revert task function back to normal function.
对测试很有用。您可以在调度任务时指定详细名称和创建者:
notify_user(user.id, verbose_name="Notify user", creator=user)