我将根据您的 can't pickle lock objects 消息进行猜测,您可能正在尝试使用包含默认 SMTP connection 的对象 pickle。
尝试不使用它 - 通过源代码查找它是具有 self._lock 的 smtp 模块。将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.connection 是None,它将尝试使用django.core.mail 中的get_connection() 来获取您的默认连接。
....或者,如果你想使用json,这也适用于connection=None:
import json
print json.dumps(msg.__dict__)
print json.dumps(email.__dict__)
这意味着您可以相当容易地编写JSONEncoder 和JSONDecoder 来序列化/反序列化您的对象,基本上使用对象的__dict__。
关于 JSON 的更多信息:
如上所示,编码__dict__ 使编码变得容易。你可以做msg.__dict__ = json.load(...),但困难的是必须在更改其值之前创建EmailMessage 对象。因此,您可以使用具有虚拟值的 EmailMessage 初始化 msg,然后分配 __dict__,或解码 JSON 并通过传递存储在JSON 到构造函数。不过,这需要您了解内部情况。
我会选择pickle,尽管存在安全隐患。
This SO question 还涵盖了其他一些替代方案。