'Passing django.core.mail.EmailMultiAlternatives instance as async_task with Django-Q
An E-mail template is build-up and send weekly to more than 2000 email recipients (bcc). I must run it as background since it takes few minutes to get rendering back and that some E-mail provider block Senders because of mass mail in a few period of time. I cannot use SendinBlue or MailChimp or any others for contractual reasons.
I use 'django.core.mail.EmailMultiAlternatives' instance in order to add images '(self.attach(img)' and documents '(self.attach_file(filepath)'. After creation all context data like <img src="cid:filename.jpg"
. I use render_to_string(template_name, request=request, context=context).strip()
to get back my filled-in HTML E-mail template.
Background running with async_task of Django-Q
When I pass my EmailMultiAlternatives
instance, I get the error:
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
If I build my instance template in the task (but with code redundancy), it works but then since I want to loop over my 2000 recipients to send the mail by chunk of 99 every n minutes (avoid mail server blocking), again, I need to pass the EmailMultiAlternatives instance
as a parameter and I get back the same error.
Any idea on how to proceed?
Solution 1:[1]
Here is the solution: https://github.com/joeyespo/django-q-email. Thanks a lot to Joe Esposito and Ankit!
As mentioned in the configuration section:
DJANGO_Q_EMAIL_USE_DICTS
- Store Python dictionaries instead of pickled EmailMessage
and EmailMultiAlternatives
(default: True)
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | openHBP |