Хорошо, благодаря комментариям @SergeyPugach, я сделал следующее:
Добавлен сигнал post_save
, который вызывает функцию, которая добавляет задачу к сельдерею. apply_async
давайте вам передадут eta
- расчетное время прибытия, которое может принять DateTimeField
напрямую, это очень удобно.
# models.py
from django.db.models import signals
from django.db import models
from .tasks import send_notification
class Notification(models.Model):
...
notify_on = models.DateTimeField()
def notification_post_save(instance, *args, **kwargs):
send_notification.apply_async((instance,), eta=instance.notify_on)
signals.post_save.connect(notification_post_save, sender=Notification)
И актуальная задача в tasks.py
import logging
from user_api.celery import app
from django.core.mail import send_mail
from django.template.loader import render_to_string
@app.task
def send_notification(self, instance):
try:
mail_subject = 'Your notification.'
message = render_to_string('notify.html', {
'title': instance.title,
'content': instance.content
})
send_mail(mail_subject, message, recipient_list=[instance.user.email], from_email=None)
except instance.DoesNotExist:
logging.warning("Notification does not exist anymore")
Я не буду вдаваться в подробности настройки сельдерея, там много информации.
Теперь я попытаюсь выяснить, как обновить задачу после обновления экземпляра уведомления, но это совсем другая история.