2010-01-12 109 views
7

大家都知道(或應該),你可以使用Django的模板系統來呈現電子郵件正文:電子郵件模板在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)), '[email protected]', [email,]) 

這在我的腦海裏有一個漏洞:編輯的主題和內容電子郵件,你必須編輯視圖和模板。雖然我可以證明給管理員用戶訪問模板的理由,但我並沒有給他們訪問原始Python的權限!

什麼將是非常酷的是,如果你能在電子郵件中指定塊,並分別將它們拉出來當您發送電子郵件:

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

但你會怎麼做呢?你將如何去渲染一個塊?

回答

11

這是我的第三次工作迭代。它假設你有一個電子郵件模板,像這樣:

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

我重構迭代的電子郵件發送了默認列表,並有實用方法發送到一個電子郵件地址和django.contrib.authUser S(單次和多次)。我涵蓋的內容可能比我明智的需要還要多,但你去了。

我也可能用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'), '[email protected]', [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) 

一如既往,如果你可以改進,請做。

+0

好&* $#我逃出來的文本。有用。考慮在基礎上添加更多字段以允許設置從/從名稱/回覆至設置。 – Oli 2010-01-12 19:19:01

+0

哈,我一直在使用三種不同的模板,這是一個PITA。來自我的確定+1! – 2010-01-12 21:28:42

+0

我喜歡它。我總是使用單獨的模板,這很好,但這樣處理起來更好(尤其是因爲您通常都希望所有模板都具有相同的上下文)。 – 2010-01-13 02:11:15

0

只需使用兩個模板:一個用於正文,一個用於主題。

+0

兩個文件意味着兩個文件名基本相同的事情。這只是一個背後的痛苦,必須保持在許多模板之上。 – Oli 2010-01-13 20:17:43

0

我不能讓模板繼承使用{% body %}標籤的工作,所以我切換到這樣的一個模板:

{% extends "base.txt" %} 

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

現在我們要呈現模板三次,但繼承正常工作。

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文本時關閉autoescape避免在電子郵件