#python #django #email #bulk-email
#python #django #Адрес электронной почты #массовая отправка электронной почты
Вопрос:
Я хочу отправлять электронные письма пользователям моего сайта, которые должны присутствовать на собрании (т. Е. гости), каждый с (одинаковым) вложением PDF. Я делаю это с помощью встроенной в Django функции массовой отправки электронной почты в connection.send_messages(messages)
. На данный момент я делаю это:
guests = Guest.objects.all()
connection = mail.get_connection()
connection.open()
messages = []
for guest in guests:
msg = EmailMultiAlternatives(title, text_content, from_address, [guest.email], connection=connection)
msg.attach_alternative(html_content, 'text/html')
pdf_data = open(os.path.join(settings.MEDIA_ROOT, 'uploads/flyer.pdf'))
msg.attach('Invitation Card.pdf', pdf_data.read(), 'application/pdf')
pdf_data.close()
messages.append(msg)
connection.send_messages(messages)
connection.close()
Теперь, когда я делаю это следующим образом, один и тот же PDF-файл будет загружен для каждого электронного письма, прикреплен отдельно, а затем отправлен отдельно для каждого электронного письма, как если бы это были разные PDF-файлы. Если размер файла составляет 10 МБ, эти 10 МБ будут загружены на мой почтовый сервер для каждого отдельного гостя, где это могло быть только один раз.
Итак, вопрос в том, можно ли прикрепить файл ко всем электронным письмам сразу, тем самым загрузив его только один раз? Или я просто делаю это неправильно?
Обновить:
Если я изменю строку прикрепления на следующую:
msg.attach_file(os.path.join(settings.MEDIA_ROOT, 'uploads/flyer.pdf'))
решит ли это мою проблему?
Ответ №1:
Глядя на django/core/mail/message.py reveals attach_file
— это просто удобная функция, которая открывает файл для вас перед вызовом attach
:
def attach_file(self, path, mimetype=None):
"""Attaches a file from the filesystem."""
filename = os.path.basename(path)
content = open(path, 'rb').read()
self.attach(filename, content, mimetype)
Вы могли бы избежать многократного открытия вложения и чтения его в память, если вы создадите подкласс EmailMultiAlternatives
и переопределите attach
метод. Вам следует изучить возможность использования для этого очереди заданий, такой как celery.
Комментарии:
1. Хм, хорошо. Спасибо, что посмотрели, мне просто было лень открывать это самому 🙂 Можете ли вы придумать какой-нибудь способ обойти эту проблему?
2. Нет, но вы можете рассмотреть возможность использования ссылки, а не фактического вложения.
3. Да, в данном случае это не совсем вариант : (
4. Вам следует подумать об использовании celery, его интеграция с django действительно великолепна. Было бы легко развернуть пакетную рассылку электронной почты как задачу и выполнять ее асинхронно на рабочем компьютере (или разбить ее и использовать несколько рабочих компьютеров).
5. Ммм, да, хорошая идея. В прошлом у меня были проблемы с тем, чтобы заставить celery работать над Webfaction (и в конечном итоге я использовал потоки python там, где это было необходимо), но, возможно, сейчас как раз то время, когда мне нужно, наконец, сесть и разобраться. Либо это, либо, по-видимому, написать какую-то пользовательскую функциональность электронной почты.