2016-06-17 6 views
0

В моем проекте django я хочу сохранить электронное письмо в базе данных, чтобы получить его позже и отправить его. Я внедряю механизм дросселирования для отправки писем многим пользователям.django - сохранение электронной почты в базе данных, чтобы иметь возможность отправить ее позже?

Я думал, что это будет так же просто, как хранить «от, субъект, тело», но потом я понял, что есть вложения, многопользовательские письма и т. Д., Есть как минимум два класса: EmailMessage и EmailMultiAlternatives ... слишком много переменных и варианты!

Я думал о хранении необработанного электронного письма, которое получает с помощью метода message(), но затем не уверен, как построить письмо обратно. Также попытался pickle, но получил can't pickle lock objects.

Любые идеи?

+0

Возможный дубликат [моделей Django, сигналов и задержки отправки электронной почты] (http://stackoverflow.com/questions/2349483/django-models-signals-and-email-sending-delay) – Anonymous

+0

Я рассматриваю это как предложение использования django-mailer для реализации дросселирования. Однако сам вопрос сильно отличается. –

+0

Это похоже на работу для сельдерея, но вам все равно понадобится способ сериализации сообщений, если вы не сериализуете на более высоком уровне. – rrauenza

ответ

1

Я собираюсь сделать предположение, основанное на вашем сообщении can't pickle lock objects, что вы можете использовать pickle свои объекты с включенным по умолчанию SMTP connection.

Попробуйте без него - grepping через источник это модуль 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', 
    '[email protected]', 
    ['[email protected]', '[email protected]'], 
    ['[email protected]'], 
    reply_to=['[email protected]'], 
    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', '[email protected]', '[email protected]' 
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, позже, когда вы звоните send() он будет пытаться использовать get_connection() от django.core.mail, чтобы получить соединение по умолчанию, если EmailMessage.connection является None.

.... С другой стороны, если вы хотите использовать 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, прежде чем вы измените его значения. Таким образом, вы можете инициализировать msg с EmailMessage, который имеет значения фиктивных значений, а затем назначить __dict__ или декодировать JSON и построить объект явно, передав аргументы (... и функции), хранящиеся в JSON, в конструктор. Это требует, чтобы вы знали внутренности.

Я бы пошел с pickle, хотя есть последствия для безопасности.

This SO question охватывает и другие альтернативы.

+0

Что делать, если я не тот, кто строит письмо, я все же могу установить соединение с None, не так ли? попробуем это и посмотрим. Благодаря!!! –

+0

Ах, ты внизу? Да, вы могли бы просто выполнить msg.connection = None', чтобы отключить его. – rrauenza

+0

да, я пишу специальный почтовый сервер, который хранит электронные письма и отправляет их позже. Благодаря! он работает: D –