7

众所周知(或应该),您可以使用 Django 的模板系统来呈现电子邮件正文:

def email(email, subject, template, context):
    from django.core.mail import send_mail
    from django.template import loader, Context

    send_mail(subject, loader.get_template(template).render(Context(context)), 'from@domain.com', [email,])

我认为这有一个缺陷:要编辑电子邮件的主题和内容,您必须同时编辑视图和模板。虽然我可以证明让管理员用户访问模板是合理的,但我并没有让他们访问原始 python!

如果您可以在电子邮件中指定块并在发送电子邮件时将它们单独拉出,那将是非常酷的:

{% block subject %}This is my subject{% endblock %}
{% block plaintext %}My body{% endblock%}
{% block html %}My HTML body{% endblock%}

但是你会怎么做呢?您将如何一次只渲染一个块?

4

3 回答 3

11

这是我的第三次工作迭代。假设您有这样的电子邮件模板:

{% block subject %}{% endblock %}
{% block plain %}{% endblock %}
{% block html %}{% endblock %}

我已经重构以默认通过列表迭代电子邮件发送,并且有用于发送到单个电子邮件和django.contrib.auth Users(单个和多个)的实用方法。我所涵盖的内容可能超出了我的合理需要,但你去吧。

我也可能对 Python 的热爱超过了顶峰。

def email_list(to_list, template_path, context_dict):
    from django.core.mail import send_mail
    from django.template import loader, Context

    nodes = dict((n.name, n) for n in loader.get_template(template_path).nodelist if n.__class__.__name__ == 'BlockNode')
    con = Context(context_dict)
    r = lambda n: nodes[n].render(con)

    for address in to_list:
        send_mail(r('subject'), r('plain'), 'from@domain.com', [address,])

def email(to, template_path, context_dict):
    return email_list([to,], template_path, context_dict)

def email_user(user, template_path, context_dict):
    return email_list([user.email,], template_path, context_dict)

def email_users(user_list, template_path, context_dict):
    return email_list([user.email for user in user_list], template_path, context_dict)

与以往一样,如果您可以改进这一点,请这样做。

于 2010-01-12T19:10:34.263 回答
0

只需使用两个模板:一个用于正文,一个用于主题。

于 2010-01-13T19:37:36.107 回答
0

我无法使用{% body %}标签让模板继承工作,所以我切换到这样的模板:

{% extends "base.txt" %}

{% if subject %}Subject{% endif %}
{% if body %}Email body{% endif %}
{% if html %}<p>HTML body</p>{% endif %}

现在我们必须渲染模板 3 次,但继承工作正常。

c = Context(context, autoescape = False)
subject = render_to_string(template_name, {'subject': True}, c).strip()
body = render_to_string(template_name, {'body': True}, c).strip()
c = Context(context, autoescape = True)
html = render_to_string(template_name, {'html': True}, c).strip()

我还发现在呈现非 HTML 文本时有必要关闭自动转义以避免电子邮件中的转义文本

于 2012-03-29T15:52:47.837 回答