Добавление асинхронных задач в приложение
Мы собираемся создать асинхронную задачу для отправки уведомления по электронной почте нашим пользователям при размещении заказа.
Конвенция говорит включить асинхронные задачи для приложения в модуль tasks в каталоге приложения. Создайте новый файл в приложении orders и назовите его tasks.py. Это место, где Celery будет искать асинхронные задачи. Добавьте в него следующий код:
from celery import task
from django.core.mail import send_mail
from .models import Order
@task
def order_created(order_id):
"""
Задача для отправки уведомления по электронной почте при успешном создании заказа.
"""
order = Order.objects.get(id=order_id)
subject = 'Order nr. {}'.format(order_id)
message = 'Dear {},\n\nYou have successfully placed an order.\
Your order id is {}.'.format(order.first_name,
order.id)
mail_sent = send_mail(subject,
message,
'[email protected]',
[order.email])
return mail_sent
Мы определяем задачу order_created с помощью декоратора task. Как вы видите, Celery-это просто функция Python, декорированная task. Функция task получает параметр order_id. При выполнении задачи всегда рекомендуется передавать только IDS функциям задач и объектам поиска. Мы используем функцию send_mail(), предоставленную с помощью Джанго для отправки уведомления по электронной почте пользователю, который разместил заказ. Если вы не хотите настраивать параметры электронной почты, можно сказать Джанго записывать электронные сообщения в консоль, добавив в файл settings.py следующий параметр:
EMAIL_BACKEND = 'django.core.mail.backends.console.EmailBackend'
Асинхронные задачи используются не только для процессов, требующих длительного времени выполнения, но и для других процессов, подверженных сбою, которые не занимают много времени для выполнения, но могут быть связаны с ошибками подключения или требуют политики повторных попыток.
Теперь мы должны добавить задачу к нашему order_create view. Откройте файл views.py приложения orders и импортируйте task следующим образом:
from .tasks import order_created
Затем вызовите order_created асинхронную задачу после корзины следующим образом:
# очистка корзины
cart.clear()
# запуск асинхронной задачи
order_created.delay(order.id)
Мы называем метод delay() задачи, чтобы выполнить ее асинхронно. Задача будет добавлена в очередь и будет выполнена как можно скорее.
Откройте еще один терминал и запустите celery, используя следующую команду:
celery -A myshop worker -l info
Теперь Celery worker работает и готов к обработке задач. Убедитесь, что сервер разработки Джанго также работает. Откройте http://127.0.0.1:8000/ в браузере, добавьте несколько товаров в корзину для покупок и завершите заказ. В терминале, в котором вы запустили Celery worker, вы увидите результат, аналогичный этому:
[2015-09-14 19:43:47,526: INFO/MainProcess] Received task: orders.
tasks.order_created[933e383c-095e-4cbd-b909-70c07e6a2ddf]
[2015-09-14 19:43:50,851: INFO/MainProcess] Task orders.tasks.
order_created[933e383c-095e-4cbd-b909-70c07e6a2ddf] succeeded in
3.318835098994896s: 1
Задача выполнена, и вы получите уведомление по электронной почте о своем заказе.