【问题标题】:Make Django build-in send_mail function working with html by default使 Django 内置 send_mail 函数默认使用 html
【发布时间】:2011-06-08 19:37:35
【问题描述】:

我想用我自己的智能 send_mail 函数替换仅适用于纯文本电子邮件的内置 send_mail 函数,该函数生成 html 和纯文本文本版本自动。对于我自己的电子邮件,一切都按预期工作,在我自己的应用程序中定义。我可以以这种方式在 views.py 中做到这一点:

from django.core import mail
from utils import send_mail as send_html_mail
mail.send_mail = send_html_mail

但第三方应用程序的电子邮件仍然会出现问题。在我的代码之前,所有导入都已经完成,并带有 send_mail 功能的猴子补丁。

是否可以在所有 django 应用程序的所有导入之前覆盖此函数?或者可能有这个问题的另一种解决方案。我真的不想通过发送这些第三方应用程序的电子邮件来修补代码。放html-template就很简单了。

【问题讨论】:

    标签: django django-email


    【解决方案1】:

    在 Django 1.7 中添加了额外的属性 html_messagesend_mail() 函数以发送 html 消息。

    https://docs.djangoproject.com/en/1.8/topics/email/#send-mail

    【讨论】:

      【解决方案2】:

      我为所有项目的应用程序编写了从纯文本电子邮件快速切换到基于 html 的电子邮件的应用程序。它无需修改任何 Django 代码或其他第三方应用程序的代码即可工作。

      在这里查看:https://github.com/ramusus/django-email-html

      【讨论】:

        【解决方案3】:

        听起来很多人都误读了您的问题。

        要覆盖从第三方模块的导入,覆盖 sys.modules['django.core.mail'] 可能会起作用。

        它适用于简单的测试,但没有经过彻底的测试。

        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
        

        例如,如果我将该代码放入我的settings.py 并启动manage.py shell 并导入send_mail,我会得到我的版本。

        我的 shell 会话

        In [1]: from django.core.mail import send_mail
        In [2]: send_mail()
        Sent!11
        

        免责声明
        我从来没有做过这样的事情,不知道有没有什么奇怪的后果。

        【讨论】:

        • 如果您有兴趣,请查看此应用程序 github.com/ramusus/django-email-html
        【解决方案4】:

        【讨论】:

        • 我的问题更深。我已经使用邮件应用程序的自定义后端。这个应用程序首先将电子邮件发送到 Db,然后通过 cron 作业发送。由于某些原因,不可能围绕 *mailer 电子邮件后端 编写包装器。因为此应用程序使用多种方式将电子邮件发送到数据库。
        • 如果您引用django-mailer,它确实有自己的后端,可以将消息放入数据库中。但是有一个设置可以更改发送邮件的后端:MAILER_EMAIL_BACKEND
        • 是的,我很清楚,谢谢。它必须有效,但我看到了这种方式的不好的一面。我们将生成、放入 DB、从 DB 中获取错误创建的电子邮件消息,并且仅在最后一刻使其正确(使用 html 和纯文本正文)。这一点都不好。例如,如果我需要通过测试覆盖这个系统,我需要将电子邮件后端切换到本地内存后端并处理生成错误的电子邮件。
        • 我实现了我的想法。如果您有兴趣,请查看此应用程序 github.com/ramusus/django-email-html
        【解决方案5】:

        来自 Django 文档: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()
        

        不需要 send_mail()。

        【讨论】:

        • 与第三方应用程序中的电子邮件有关的问题,我不会重写。他们使用内置的 send_mail 功能,但我想将我网站的所有电子邮件切换到 html 版本。
        • 如果您有兴趣,请查看此应用程序github.com/ramusus/django-email-html
        【解决方案6】:

        稍微改变一下django 并用你自己的函数替换原始代码怎么样?实际上,您可以只添加自己的函数而不删除旧函数,因为最后一个定义将被导入。我不喜欢这样的解决方案,因为我不喜欢修补外部库(你需要记住升级时再次修补它们),但这会很快解决你的问题。

        【讨论】:

        • 谢谢。这是可能的,但我找到了一个更清洁的解决方案,如果我可以这样称呼这样的解决方案:-)。无需修改django代码
        • 如果您有兴趣,请查看此应用程序github.com/ramusus/django-email-html
        • 您究竟是如何替换旧的发送功能的?为什么现在它发生在其他模块导入它之前?我很想知道,能够再次使用这个技巧。
        • 是的,这听起来很合理。尽管依赖于加载模块的顺序似乎有点冒险。我想知道,无论如何导入模块都可以实现这一点。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2015-08-10
        • 2013-06-11
        • 2016-12-20
        • 2018-10-26
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多