django - 将电子邮件保存到数据库以便稍后发送?

django - persisting an email to database to be able to send it later?

在我的 Django 项目中,我想在数据库中存储一封电子邮件,以便稍后检索并发送。我正在实施一种向许多用户发送电子邮件的限制机制。

我以为它会像存储一样简单 'to, from, subject, body' 但后来我意识到有附件,多部分电子邮件等,至少有两个 类 EmailMessageEmailMultiAlternatives...变量和选项太多!

我考虑过存储使用 message() 方法收到的原始电子邮件,但后来不确定如何构造电子邮件。还尝试了 pickle 但得到了 can't pickle lock objects.

有什么想法吗?

我将根据您的 can't pickle lock objects 消息进行猜测,您可能正在尝试 pickle 使用包含默认 SMTP connection 的对象。

不带它试试看 - 通过源代码搜索它是 smtp 模块,它有一个 self._lock。将 connection=None 传递给消息的构造函数。

在 Django 1.9 上,这对我有用 (Python2):

from django.core.mail import EmailMessage
from django.core.mail import EmailMultiAlternatives
import pickle

email = EmailMessage(
    'Hello',
    'Body goes here',
    'from@example.com',
    ['to1@example.com', 'to2@example.com'],
    ['bcc@example.com'],
    reply_to=['another@example.com'],
    headers={'Message-ID': 'foo'},
    connection=None,
)

email.attach("foo", [l for l in open(__file__)], 'text')

print len(pickle.dumps(email))

subject, from_email, to = 'hello', 'from@example.com', 'to@example.com'
text_content = 'This is an important message.'
html_content = '<p>This is an <strong>important</strong> message.</p>'
msg = EmailMultiAlternatives(subject, text_content, from_email, [to], connection=None)
msg.attach_alternative(html_content, "text/html")

print len(pickle.dumps(msg))

根据 messages.py 中的 Django 代码,稍后当您调用 send() 时,如果 EmailMessage.connectionNone.

...或者,如果您想使用 json,这也适用于 connection=None:

import json                                                            
print json.dumps(msg.__dict__)                                         
print json.dumps(email.__dict__)

这意味着您可以很容易地将 JSONEncoderJSONDecoder 写入 serialize/deserialize 您的对象,基本上使用对象的 __dict__

有关 JSON 的更多信息:

如上所示,对 __dict__ 进行编码使编码变得容易。您可以执行 msg.__dict__ = json.load(...),但困难的是必须在更改其值之前创建 EmailMessage 对象。因此,您可以使用具有虚拟值的 EmailMessage 初始化 msg,然后分配 __dict__,或者解码 JSON 并通过传递参数 (. ..and functions) 存储在 JSON 到构造函数中。不过,这需要您了解内部结构。

我会选择 pickle,尽管存在安全隐患。

This SO question 也涵盖了其他一些选择。