在 Django 中发送 HTML 邮件

21
在我的项目中,我添加了一个通讯订阅功能。但是在试图使用此功能发送电子邮件时:
def send(request):
    template_html = 'static/newsletter.html'
    template_text = 'static/newsletter.txt'
    newsletters = Newsletter.objects.filter(sent=False)
    subject = _(u"Newsletter")
    adr = NewsletterEmails.objects.all()
    for a in adr:
        for n in newsletters:
            to = a.email
            from_email = settings.DEFAULT_FROM_EMAIL           
            subject = _(u"Newsletter Fandrive")
            text = get_template(template_text)
            html = get_template(template_html)
            d = { 'n': n,'email': to }
            text_content = text.render(d)
            html_content = html.render(d)

            msg = EmailMultiAlternatives(subject, text_content, from_email, [to])
            msg.attach_alternative(html_content, "text/html")
            msg.send()

使用这些模板:

//text

===================  Newsletter - {{ n.date }}  ============
==========================================================
                      {{ n.title }}
==========================================================          
{{ n.text }}
==========================================================

//html

<html>
    <head>
    </head>
    <body>
    <div style="">
        <div style="">
            <h1 style="">{{ n.title }} - {{n.date}}</h1>
                <p style="">            
                    {{ n.text }}
                </p>
        </div>
    </div>
    </body>
</html>

并且模型:

class Newsletter(models.Model):
    title = models.CharField("title", blank=False, max_length=50)
    text = models.TextField("text", blank=False)
    sent = models.BooleanField("sent", default=False)
    data = models.DateTimeField("creation date", auto_now_add=True, blank=False)

class NewsletterEmails(models.Model):
    email = models.EmailField(_(u"e-mail address"),)

我遇到了以下错误:

TemplateSyntaxError at /utils/newsletter_send/
Caught an exception while rendering: 'dict' object has no attribute 'autoescape'

错误发生在text_email模板中的{{ n.date }}位置。

我调试代码时发现我已经将newsletter对象正确传递到了模板中,并且调试上下文也正常:

context {'email': u'admin@domain.com', 'n': <Newsletter: Newsletter object>}

为什么会出现这种情况?从我对该错误的研究中得知,它与向模板渲染器发送空字典有关,但我的字典并不为空……


在您的模型定义中,日期字段被命名为“data”,这是在发布问题时的笔误还是在代码中也是如此? - Ashok
错别字,到处都是日期。不知道怎么会发生这种事... :) - crivateos
在 #django 日志中,我读到了“您正在将字典传递给期望 Context 对象的某个东西。”。如何解决这个问题? - crivateos
3个回答

19

仅供参考。我找到了另一种做法:

def send(request):
    template_html = 'static/newsletter.html'
    template_text = 'static/newsletter.txt'
    newsletters = Newsletter.objects.filter(sent=False)
    subject = _(u"Newsletter Fandrive")
    adr = NewsletterEmails.objects.all()
    for a in adr:
        for n in newsletters:
            to = a.email
            from_email = settings.DEFAULT_FROM_EMAIL           
            subject = _(u"Newsletter Fandrive")

            text_content = render_to_string(template_text, {"title": n.title,"text": n.text, 'date': n.date, 'email': to})
            html_content = render_to_string(template_html, {"title": n.title,"text": n.text, 'date': n.date, 'email': to})

            msg = EmailMultiAlternatives(subject, text_content, from_email, [to])
            msg.attach_alternative(html_content, "text/html")
            msg.send()

    return HttpResponseRedirect('/')

2
你忘记了导入语句 from django.core.mail import EmailMultiAlternatives - Craig Labenz
1
这个是用来发送HTML邮件的吗?还是有其他的工作方式?我正在尝试这种方法,但是我只收到了文本消息。 - André Fratelli

12

他们已经更新send_mail函数,使其允许在开发版本中发送包含HTML的邮件。

def send(request):
    template_html = 'static/newsletter.html'
    template_text = 'static/newsletter.txt'
    newsletters = Newsletter.objects.filter(sent=False)
    subject = _(u"Newsletter Fandrive")
    adr = NewsletterEmails.objects.all()
    for a in adr:
        for n in newsletters:
            to = a.email
            from_email = settings.DEFAULT_FROM_EMAIL           
            subject = _(u"Newsletter Fandrive")

            text_content = render_to_string(template_text, {"title": n.title,"text": n.text, 'date': n.date, 'email': to})
            html_content = render_to_string(template_html, {"title": n.title,"text": n.text, 'date': n.date, 'email': to})

            send_mail(subject, text_content, from_email,
             to, fail_silently=False, html_message=html_content)
    return HttpResponseRedirect('/')

10

这是一个相当简单的修复方法,你只是遗漏了一个微小的东西。

你正在做这个:

  d = { 'n': n,'email': to }

尝试将该字典用作render()方法的一部分,然后:

但是,render需要一个Context,所以您需要执行以下操作:

 d = Context({ 'n': n,'email': to })

确保也从 django.template 中导入它。这样应该可以解决您正在遇到的错误。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接