Django Html 邮件在邮件正文中添加额外字符

63 阅读2分钟

在使用 Django 发送包含文本部分和 HTML 部分的电子邮件时,发现电子邮件中包含了额外的字符 "Content-Type: text/html; charset=utf-8"。

huake_00210_.jpg 以下是如何发送电子邮件的代码:

subject = request.session.get('email_subject', None)
from_email = request.session.get('user_email', None)
to = request.session.get('user_email', None)
bcc = [email.strip() for email in request.session.get('email_recipients', None).split(settings.EMAIL_DELIMITER)]

text_content = render_to_response(email_text_template, {
    'body': request.session.get('email_body', None),
    'link': "http://%(site_url)s/ecard/?%(encoded_greeting)s" % {
        'site_url': settings.SITE_URL,
        'encoded_greeting': urlencode({'g': quote_plus(request.session.get('card_greeting'))}),
    },
}, context_instance=RequestContext(request))

html_content = render_to_response(email_html_template, {
    'body': request.session.get('email_body', None),
    'link': "http://%(site_url)s/ecard/?%(encoded_greeting)s" % {
        'site_url': settings.SITE_URL,
        'encoded_greeting': urlencode({'g': request.session.get('card_greeting')}),
    },
    'site_url': settings.SITE_URL,
}, context_instance=RequestContext(request))

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

当用户收到电子邮件时,会发现其中包含了多余的字符 "Content-Type: text/html; charset=utf-8"。

2、解决方案

方法一:使用 render_to_string 函数

正如 Alasdair 在回答中指出的,使用 render_to_response 函数时,它返回一个 HttpResponse 对象。而我们需要将 html_contenttext_content 设置为字符串,因此应该使用 render_to_string 函数。

from django.template.loader import render_to_string

html_content = render_to_string(email_html_template, {
    'body': request.session.get('email_body', None),
    'link': "http://%(site_url)s/ecard/?%(encoded_greeting)s" % {
        'site_url': settings.SITE_URL,
        'encoded_greeting': urlencode({'g': request.session.get('card_greeting')}),
    },
    'site_url': settings.SITE_URL,
})

text_content = render_to_string(email_text_template, {
    'body': request.session.get('email_body', None),
    'link': "http://%(site_url)s/ecard/?%(encoded_greeting)s" % {
        'site_url': settings.SITE_URL,
        'encoded_greeting': urlencode({'g': quote_plus(request.session.get('card_greeting'))}),
    },
})

方法二:使用 shell 调试

如果对 render_to_stringrender_to_response 这两个函数的输出感到困惑,也可以使用 shell 调试来查看它们的输出。

$ ./manage.py shell
Python 2.6.3 (r263:75183, Oct 14 2009, 15:40:24) 
Type "help", "copyright", "credits" or "license" for more information.
>>> from django.shortcuts import render_to_response
>>> from django.template.loader import render_to_string
>>> template = 'your_template.html'
>>> print( "\n".join(render_to_string(template).split('\n')[:3]) )
template-line-1
template-line-2
template-line-3
>>> print( "\n".join(str(render_to_response(template)).split('\n')[:3]) )
Content-Type: text/html; charset=utf-8

template-line-1
>>>

从输出中可以看出,render_to_string 函数返回的是模板中的内容,而 render_to_response 函数返回了一个 HttpResponse 对象,它的头部包含了 "Content-Type: text/html; charset=utf-8"。