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,])

これには1つの欠点があります。メールの件名と内容を編集するには、ビューとテンプレートの両方を編集する必要があります。管理者ユーザーにテンプレートへのアクセスを許可することは正当化できますが、生のPythonへのアクセスを許可するわけではありません。

本当にすばらしいのは、電子メールでブロックを指定し、電子メールを送信するときにそれらを個別に引き出すことができる場合です。

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

しかし、どうやってそれをしますか?一度に1つのブロックだけをレンダリングするにはどうすればよいですか?

4

3 に答える 3

11

これは私の 3 回目の反復作業です。次のようなメール テンプレートがあると仮定します。

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

デフォルトでリストを介して電子メールを送信するようにリファクタリングしました。単一の電子メールとdjango.contrib.auth Users (単一および複数) に送信するためのユーティリティ メソッドがあります。私はおそらく私が賢明に必要とする以上のものをカバーしていますが、それで終わりです。

私はまた、Python-love を使いすぎたかもしれません。

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

タグを使用してテンプレートの継承を機能させることができなかった{% 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 に答える
0

本文用と件名用の 2 つのテンプレートを使用するだけです。

于 2010-01-13T19:37:36.107 に答える