Передача экземпляра django.core.mail.EmailMultiAlternatives в качестве async_task с помощью Django-Q
Создан шаблон электронной почты и еженедельно рассылается более чем 2000 адресатам (bcc). Я должен запускать его в фоновом режиме, так как это занимает несколько минут, чтобы получить рендеринг обратно, и что некоторые провайдеры блокируют отправителей из-за массовой рассылки в течение нескольких периодов времени. Я не могу использовать SendinBlue или MailChimp или любые другие по контрактным причинам.
Я использую экземпляр 'django.core.mail.EmailMultiAlternatives' для добавления изображений '(self.attach(img)' и документов '(self.attach_file(filepath)'. После создания всех контекстных данных типа <img src="cid:filename.jpg". Я использую render_to_string(template_name, request=request, context=context).strip(), чтобы получить обратно мой заполненный шаблон HTML E-mail.
В фоновом режиме выполняется async_task из Django-Q
Когда я передаю свой экземпляр EmailMultiAlternatives, я получаю ошибку:
Traceback (most recent call last):
File ".pyenv/versions/3.9.7/lib/python3.9/multiprocessing/queues.py", line 245, in _feed
obj = _ForkingPickler.dumps(obj)
File ".pyenv/versions/3.9.7/lib/python3.9/multiprocessing/reduction.py", line 51, in dumps
cls(buf, protocol).dump(obj)
TypeError: cannot pickle '_thread.RLock' object
Если я создаю свой шаблон экземпляра в задаче (но с избыточным кодом), он работает, но затем, поскольку я хочу перебирать 2000 получателей, чтобы отправлять письма по 99 каждые n минут (избежать блокировки почтового сервера), мне снова нужно передать EmailMultiAlternatives instance в качестве параметра, и я получаю ту же ошибку.
Есть идеи, как действовать дальше?
Вот решение: https://github.com/joeyespo/django-q-email. Большое спасибо Джо Эспозито и Анкиту!
Как упоминалось в разделе конфигурации:
DJANGO_Q_EMAIL_USE_DICTS - Хранить словари Python вместо маринованных EmailMessage и EmailMultiAlternatives (по умолчанию: True)