I want to substitute build-in send_mail function, that works only with plain-text emails, with my own smart send_mail function, that generates both html and plain-text versions automatically. Everything works as expected for my own emails, defined in my own application. I can do it in views.py in this fashion:
from django.core import mail
from utils import send_mail as send_html_mail
mail.send_mail = send_html_mail
But the problem still appears with emails of third-side applications. There all imports already completed before my code with monkey-patching of send_mail function.
Is it possible to override this function before all imports of all django applications? Or may be there is another solution of this issue. I really don't want to patch code with sending emails of these third-party applications. It's much easy just to put html-template.
Django 1.2 allows for pluggable email backends: http://docs.djangoproject.com/en/1.2/topics/email/#defining-a-custom-e-mail-backend
From Django docs: http://docs.djangoproject.com/en/dev/topics/email/#sending-alternative-content-types
from django.core.mail import EmailMultiAlternatives
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])
msg.attach_alternative(html_content, "text/html")
msg.send()
No send_mail() required.
Sounds like a lot of people are misreading your question.
To override the import from third party modules, overwriting sys.modules['django.core.mail']
might work.
It works in simple tests, but it's not thoroughly tested.
import sys
from django.core import mail
def my_send_mail(*args, **kwargs):
print "Sent!11"
mail.send_mail = my_send_mail
sys.modules['django.core.mail'] = mail
from django.core.mail import send_mail
send_mail('blah')
# output: Sent!11
For example, if I put that code in my settings.py
and launch the manage.py shell
and import send_mail
, I get my version.
My shell session
In [1]: from django.core.mail import send_mail
In [2]: send_mail()
Sent!11
Disclaimer
I've never done anything like this and don't know if there are any funky ramifications.
I wrote application for quickly switching from plain-text emails to html based emails for all project's applications. It will work without modifying any Django code or code of other third-part applications.
Check it out here: https://github.com/ramusus/django-email-html
How about changing django
a little and substituting original code with your own function? You can actually just add your own function and don't remove the old, as the last definition will be imported. I don't like such solutions, because I don't like patching external libraries (you need to remember about patching them again when you upgrade), but this would solve your problem quickly.
In Django 1.7 added extra attribute html_message
to send_mail()
function to send html message.
https://docs.djangoproject.com/en/1.8/topics/email/#send-mail
来源:https://stackoverflow.com/questions/4685774/make-django-build-in-send-mail-function-working-with-html-by-default