我正在努力解决以下问题。
我正在尝试创建一个自定义信号,该信号将在当前时间等于模型的notify_on DateTimeField
的值时触发。
类似这样的东西:
class Notification(models.Model):
...
notify_on = models.DateTimeField()
def send_email(*args, **kwargs):
# send email
signals.when_its_time.connect(send_email, sender=User)
阅读完所有文档后,我没有发现有关如何实现此类信号的信息。
有什么想法吗?
更新: 较幼稚的方法,可以丢弃无关的任务:https://stackoverflow.com/a/55337663/9631956
答案 0 :(得分:2)
在django的文档中,有两个有趣的信号可以帮助您完成此任务:pre_save和post_save。
这取决于您的需求,但是,假设您要在保存模型后检查模型的notify_on
是否等于当前日期(实际上是在调用save()
或create()
方法之后)。如果是您的情况,可以执行以下操作:
from datetime import datetime
from django.contrib.auth.models import User
from django.db import models
from django.dispatch import receiver
from django.db.models.signals import post_save
class Notification(models.Model):
...
# Every notification is related to a user
# It depends on your model, but i guess you're doing something similar
user = models.ForeignKey(User, related_name='notify', on_delete=models.DO_NOTHING)
notify_on = models.DateTimeField()
...
def send_email(self, *args, **kwargs):
"""A model method to send email notification"""
...
@receiver(post_save, sender=User)
def create_notification(sender, instance, created, **kwargs):
# check if the user instance is created
if created:
obj = Notification.objects.create(user=instance, date=datetime.now().date())
if obj.notify_on == datetime.now().date():
obj.send_email()
您应该知道,只有有触发它们的动作,django信号才能由它们自己拥有。这意味着Django信号不会在模型的实例上循环并执行操作,但是django信号将在您的应用程序对连接到信号的模型执行操作时触发。
奖励::要对实例执行循环并定期处理操作,您可能需要具有async
数据库(主要是Queue
)的Celery
工作人员Redis or RabbitMQ
)。
答案 1 :(得分:1)
好,感谢@SergeyPugach的评论,我做了以下工作:
添加了一个var photo = true; // Will capture picture.
if (photo) { // 'true' is a truthy value.
capturePhoto();
} else {
// Do nothing
}
信号,该信号调用了一个将任务添加到芹菜的函数。 @ClientEndpoint
class MyClientEndpoint {
@OnOpen
def onOpen(session: Session): Unit = {
log.debug("New session opened: " + session.getId)
}
@OnClose
def onClose(session: Session, reason: CloseReason): Unit = {
log.debug(s"Session[${session.getId}] closed: " + reason)
}
@OnMessage
def onMessage(message: String): Unit = {
log.debug("Received: " + message)
}
}
让您通过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)
我不会介绍设置芹菜的细节,那里有很多信息。
现在,我将尝试找出在通知实例更新后如何更新任务,但这是一个完全不同的故事。