Define email subject in a Django template

Question:

Say I want to send an email using the send_mail() method. The body of the email lives in templates/email.html. I would like to define the email subject in the same file to keep things in one place.
But send_mail() needs the subject in a separate variable.

So I came up with an ugly hacky way to do it. I start the template like this:

{% comment "The second line of this template will be used as email subject" %}
Congratulations, your account was created!
{% endcomment %}

And then extract it in the code like this:

template = loader.get_template('email.html')
subject = template.template.source.splitlines()[1]

This works, but I dislike this solution. Is there an easier and more readable way to do this?

More generally, can I define a variable in Django template and then extract it in the application? Something like template.get_variable("email_subject")?

Asked By: David Hás

||

Answers:

I would do this the way Django does by having two separate templates, one for the subject and one for the body.

subject = loader.render_to_string(subject_template_name, context)
# Email subject *must not* contain newlines
subject = "".join(subject.splitlines())
body = loader.render_to_string(email_template_name, context)

You can see an example in Django’s codebase for their forgot password email https://github.com/django/django/blob/9ac3ef59f9538cfb520e3607af743532434d1755/django/contrib/auth/forms.py#L274

Answered By: Jimmy Pells

I have tried a solutions for this type of problem and its working for me.

  1. I have model definition like
subject_line = models.TextField(null=True, blank=True, help_text=_("Initially used as email subject line.")
  1. Then I populated it with the following templates
{% load i18n %}{% autoescape off %}
{% blocktranslate %} Confirmation for order number:{{order_number}}, order reference:{{order_reference}}, po nummer:{{po_number}}, customer reference:{{customer_reference}} {% endblocktranslate %}
{% endautoescape %}
  1. Updated the related logics like
from django.template import Context, Template
 
subject_context = {
                "order_reference": order.reference,
                "order_number": order.id,
                "po_number": order.po_number,
                "customer_reference": order.customer_reference,
            }
subject_context_obj = Context(subject_context)
email_subject_template_obj =Template(email_template_obj.subject_line)
subject = email_subject_template_obj.render(context=subject_context_obj)
subject = "".join(subject.splitlines()).strip()

email = EmailMessage(
            subject=subject,
            body=body,
            to=to_email
        )
  1. The subject is become Confirmation for Order Number:886, Order Reference:H00000886, PO Number:PO-1234, Customer Reference:Sharif 1234
Answered By: sharif_42
Categories: questions Tags: , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.