summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMartin Blech <martinblech@gmail.com>2014-11-25 20:05:44 -0300
committerTim Graham <timograham@gmail.com>2014-11-28 06:00:06 -0500
commite023ceb453c02e271d00f9ac25e154b7be712bb0 (patch)
treef884b6a0bc57c16ec6d3665f419a2043eda153b2
parent6b5d82749c57a1aae8c9e81d2b85b2cadb9ef933 (diff)
Fixed #23910 -- Added reply_to parameter to EmailMessage
Thanks to Berker Peksag and Tim Graham for the review and suggestions.
-rw-r--r--django/core/mail/message.py16
-rw-r--r--docs/releases/1.8.txt3
-rw-r--r--docs/topics/email.txt9
-rw-r--r--tests/mail/tests.py28
4 files changed, 52 insertions, 4 deletions
diff --git a/django/core/mail/message.py b/django/core/mail/message.py
index c076945f42..8d2dc0b72d 100644
--- a/django/core/mail/message.py
+++ b/django/core/mail/message.py
@@ -214,7 +214,8 @@ class EmailMessage(object):
encoding = None # None => use settings default
def __init__(self, subject='', body='', from_email=None, to=None, bcc=None,
- connection=None, attachments=None, headers=None, cc=None):
+ connection=None, attachments=None, headers=None, cc=None,
+ reply_to=None):
"""
Initialize a single email message (which can be sent to multiple
recipients).
@@ -241,6 +242,12 @@ class EmailMessage(object):
self.bcc = list(bcc)
else:
self.bcc = []
+ if reply_to:
+ if isinstance(reply_to, six.string_types):
+ raise TypeError('"reply_to" argument must be a list or tuple')
+ self.reply_to = list(reply_to)
+ else:
+ self.reply_to = []
self.from_email = from_email or settings.DEFAULT_FROM_EMAIL
self.subject = subject
self.body = body
@@ -263,6 +270,8 @@ class EmailMessage(object):
msg['To'] = self.extra_headers.get('To', ', '.join(self.to))
if self.cc:
msg['Cc'] = ', '.join(self.cc)
+ if self.reply_to:
+ msg['Reply-To'] = self.extra_headers.get('Reply-To', ', '.join(self.reply_to))
# Email header names are case-insensitive (RFC 2045), so we have to
# accommodate that when doing comparisons.
@@ -395,7 +404,7 @@ class EmailMultiAlternatives(EmailMessage):
def __init__(self, subject='', body='', from_email=None, to=None, bcc=None,
connection=None, attachments=None, headers=None, alternatives=None,
- cc=None):
+ cc=None, reply_to=None):
"""
Initialize a single email message (which can be sent to multiple
recipients).
@@ -405,7 +414,8 @@ class EmailMultiAlternatives(EmailMessage):
conversions.
"""
super(EmailMultiAlternatives, self).__init__(
- subject, body, from_email, to, bcc, connection, attachments, headers, cc
+ subject, body, from_email, to, bcc, connection, attachments,
+ headers, cc, reply_to,
)
self.alternatives = alternatives or []
diff --git a/docs/releases/1.8.txt b/docs/releases/1.8.txt
index ffdd33c12f..fb4e44576c 100644
--- a/docs/releases/1.8.txt
+++ b/docs/releases/1.8.txt
@@ -210,6 +210,9 @@ Email
* The SMTP :class:`~django.core.mail.backends.smtp.EmailBackend` now supports
setting the ``timeout`` parameter with the :setting:`EMAIL_TIMEOUT` setting.
+* :class:`~django.core.mail.EmailMessage` and ``EmailMultiAlternatives`` now
+ support the ``reply_to`` parameter.
+
File Storage
^^^^^^^^^^^^
diff --git a/docs/topics/email.txt b/docs/topics/email.txt
index 7333ae7110..aabe66085e 100644
--- a/docs/topics/email.txt
+++ b/docs/topics/email.txt
@@ -278,11 +278,18 @@ All parameters are optional and can be set at any time prior to calling the
* ``cc``: A list or tuple of recipient addresses used in the "Cc" header
when sending the email.
+* ``reply_to``: A list or tuple of recipient addresses used in the "Reply-To"
+ header when sending the email.
+
+.. versionchanged:: 1.8
+
+ The ``reply_to`` parameter was added.
+
For example::
email = EmailMessage('Hello', 'Body goes here', 'from@example.com',
['to1@example.com', 'to2@example.com'], ['bcc@example.com'],
- headers = {'Reply-To': 'another@example.com'})
+ reply_to=['another@example.com'], headers={'Message-ID': 'foo'})
The class has the following methods:
diff --git a/tests/mail/tests.py b/tests/mail/tests.py
index a34a862622..e4b568939c 100644
--- a/tests/mail/tests.py
+++ b/tests/mail/tests.py
@@ -89,6 +89,21 @@ class MailTests(HeadersCheckMixin, SimpleTestCase):
self.assertEqual(message['Cc'], 'cc@example.com, cc.other@example.com')
self.assertEqual(email.recipients(), ['to@example.com', 'other@example.com', 'cc@example.com', 'cc.other@example.com', 'bcc@example.com'])
+ def test_reply_to(self):
+ email = EmailMessage(
+ 'Subject', 'Content', 'from@example.com', ['to@example.com'],
+ reply_to=['reply_to@example.com'],
+ )
+ message = email.message()
+ self.assertEqual(message['Reply-To'], 'reply_to@example.com')
+
+ email = EmailMessage(
+ 'Subject', 'Content', 'from@example.com', ['to@example.com'],
+ reply_to=['reply_to1@example.com', 'reply_to2@example.com']
+ )
+ message = email.message()
+ self.assertEqual(message['Reply-To'], 'reply_to1@example.com, reply_to2@example.com')
+
def test_recipients_as_tuple(self):
email = EmailMessage('Subject', 'Content', 'from@example.com', ('to@example.com', 'other@example.com'), cc=('cc@example.com', 'cc.other@example.com'), bcc=('bcc@example.com',))
message = email.message()
@@ -102,6 +117,8 @@ class MailTests(HeadersCheckMixin, SimpleTestCase):
EmailMessage(cc='foo@example.com')
with self.assertRaisesMessage(TypeError, '"bcc" argument must be a list or tuple'):
EmailMessage(bcc='foo@example.com')
+ with self.assertRaisesMessage(TypeError, '"reply_to" argument must be a list or tuple'):
+ EmailMessage(reply_to='reply_to@example.com')
def test_header_injection(self):
email = EmailMessage('Subject\nInjection Test', 'Content', 'from@example.com', ['to@example.com'])
@@ -163,6 +180,17 @@ class MailTests(HeadersCheckMixin, SimpleTestCase):
self.assertEqual(message['To'], 'list-subscriber@example.com, list-subscriber2@example.com')
self.assertEqual(email.to, ['list-subscriber@example.com', 'list-subscriber2@example.com'])
+ def test_reply_to_header(self):
+ """
+ Specifying 'Reply-To' in headers should override reply_to.
+ """
+ email = EmailMessage(
+ 'Subject', 'Content', 'bounce@example.com', ['to@example.com'],
+ reply_to=['foo@example.com'], headers={'Reply-To': 'override@example.com'},
+ )
+ message = email.message()
+ self.assertEqual(message['Reply-To'], 'override@example.com')
+
def test_multiple_message_call(self):
"""
Regression for #13259 - Make sure that headers are not changed when