문제

우리 모두가 알고 있듯이 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,])

이것은 내 마음에 한 가지 결함이 있습니다. 이메일의 주제와 내용을 편집하려면보기와 템플릿을 모두 편집해야합니다. 관리자 사용자가 템플릿에 액세스 할 수있는 것을 정당화 할 수는 있지만 원시 파이썬에 액세스 할 수는 없습니다!

정말 멋진 점은 이메일에 블록을 지정하고 이메일을 보낼 때 별도로 꺼낼 수 있다면 다음과 같습니다.

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

하지만 어떻게 하시겠습니까? 한 번에 한 블록 만 렌더링하는 방법은 무엇입니까?

도움이 되었습니까?

해결책

이것은 나의 세 번째 작업 반복입니다. SO와 같은 이메일 템플릿이 있다고 가정합니다.

{% 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)

그 어느 때보 다 개선 할 수 있다면,하십시오.

다른 팁

두 개의 템플릿을 사용하십시오.

나는 템플릿 상속을 사용할 수 없었다 {% 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를 끄는 것이 필요하다는 것을 알았습니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top