如何在Django中安排未来发送邮件?
我想安排在用户进行某个特定操作时发送一封邮件给他们。可是,如果用户又进行了其他操作,我希望能取消这封邮件,让它不被发送。
我该怎么在django或者python中实现这个功能呢?
5 个回答
2
如果你没有办法使用 cron
,你可以简单地这样做:
- 先写一个模型,用来存储电子邮件、发送时间,还有一个
BooleanField
来表示这封邮件是否已经发送过。 - 然后写一个视图,选择所有还没发送但应该发送的邮件,并把它们发送出去。
- 接着使用像 OpenACS Uptime、Pingdom 这样的服务,或者其他能定期发送
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,从而发送邮件。