如何在Django中安排未来发送邮件?

2 投票
5 回答
5260 浏览
提问于 2025-04-16 10:13

我想安排在用户进行某个特定操作时发送一封邮件给他们。可是,如果用户又进行了其他操作,我希望能取消这封邮件,让它不被发送。

我该怎么在django或者python中实现这个功能呢?

5 个回答

2

如果你没有办法使用 cron,你可以简单地这样做:

  1. 先写一个模型,用来存储电子邮件、发送时间,还有一个 BooleanField 来表示这封邮件是否已经发送过。
  2. 然后写一个视图,选择所有还没发送但应该发送的邮件,并把它们发送出去。
  3. 接着使用像 OpenACS UptimePingdom 这样的服务,或者其他能定期发送 HTTP GET 请求的服务,来调用这个视图,触发邮件发送。(这两个服务都是免费的,前者每15分钟请求一次,后者可以设置每分钟请求一次,并且会从多个地方发起请求。)

当然,这种方法不太优雅,但在几乎所有的网络主机上都能用。我以前在写PHP应用的时候也用过类似的方法,因为我的主机在15秒后就会终止所有进程。

3

我会设置一个定时任务,这样就可以处理你想做的所有事情...

4

Beanstalkd

如果你能安装beanstalkd并且能从命令行运行Python脚本,我建议你用它来安排发送邮件。通过beanstalkc这个客户端,你可以很简单地做到这一点。在Ubuntu系统上,你可能需要先安装:

  • sudo apt-get install python-yaml python-setuptools

consumer.py:

import beanstalkc

def main():
    beanstalk = beanstalkc.Connection(host='localhost', port=11300)
    while True:
        job = beanstalk.reserve()
        print job.body
        job.delete()


if __name__ == '__main__':
    main()

这个脚本会在生产者脚本(producer.py)插入任务后5秒钟打印出来。当然,你可以设置更长的时间来安排你的邮件发送,但为了演示,这个时间就够了。测试的时候可不想等半个小时才发送消息;)

producer.py:

import beanstalkc

def main():
    beanstalk = beanstalkc.Connection(host='localhost', port=11300)
    jid = beanstalk.put('foo', delay=5)

if __name__ == '__main__':
    main()

GAE任务队列

你也可以使用Google App Engine的任务队列来实现这个功能。你可以为你的任务指定一个eta(预计时间)。Google App Engine提供了慷慨的免费配额。在任务队列的Webhook中,可以进行异步请求,来获取你服务器上的URL,从而发送邮件。

撰写回答