Fixed #23910 -- Added reply_to parameter to EmailMessage
Thanks to Berker Peksag and Tim Graham for the review and suggestions.
This commit is contained in:
parent
6b5d82749c
commit
e023ceb453
|
@ -214,7 +214,8 @@ class EmailMessage(object):
|
||||||
encoding = None # None => use settings default
|
encoding = None # None => use settings default
|
||||||
|
|
||||||
def __init__(self, subject='', body='', from_email=None, to=None, bcc=None,
|
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
|
Initialize a single email message (which can be sent to multiple
|
||||||
recipients).
|
recipients).
|
||||||
|
@ -241,6 +242,12 @@ class EmailMessage(object):
|
||||||
self.bcc = list(bcc)
|
self.bcc = list(bcc)
|
||||||
else:
|
else:
|
||||||
self.bcc = []
|
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.from_email = from_email or settings.DEFAULT_FROM_EMAIL
|
||||||
self.subject = subject
|
self.subject = subject
|
||||||
self.body = body
|
self.body = body
|
||||||
|
@ -263,6 +270,8 @@ class EmailMessage(object):
|
||||||
msg['To'] = self.extra_headers.get('To', ', '.join(self.to))
|
msg['To'] = self.extra_headers.get('To', ', '.join(self.to))
|
||||||
if self.cc:
|
if self.cc:
|
||||||
msg['Cc'] = ', '.join(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
|
# Email header names are case-insensitive (RFC 2045), so we have to
|
||||||
# accommodate that when doing comparisons.
|
# accommodate that when doing comparisons.
|
||||||
|
@ -395,7 +404,7 @@ class EmailMultiAlternatives(EmailMessage):
|
||||||
|
|
||||||
def __init__(self, subject='', body='', from_email=None, to=None, bcc=None,
|
def __init__(self, subject='', body='', from_email=None, to=None, bcc=None,
|
||||||
connection=None, attachments=None, headers=None, alternatives=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
|
Initialize a single email message (which can be sent to multiple
|
||||||
recipients).
|
recipients).
|
||||||
|
@ -405,7 +414,8 @@ class EmailMultiAlternatives(EmailMessage):
|
||||||
conversions.
|
conversions.
|
||||||
"""
|
"""
|
||||||
super(EmailMultiAlternatives, self).__init__(
|
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 []
|
self.alternatives = alternatives or []
|
||||||
|
|
||||||
|
|
|
@ -210,6 +210,9 @@ Email
|
||||||
* The SMTP :class:`~django.core.mail.backends.smtp.EmailBackend` now supports
|
* The SMTP :class:`~django.core.mail.backends.smtp.EmailBackend` now supports
|
||||||
setting the ``timeout`` parameter with the :setting:`EMAIL_TIMEOUT` setting.
|
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
|
File Storage
|
||||||
^^^^^^^^^^^^
|
^^^^^^^^^^^^
|
||||||
|
|
||||||
|
|
|
@ -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
|
* ``cc``: A list or tuple of recipient addresses used in the "Cc" header
|
||||||
when sending the email.
|
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::
|
For example::
|
||||||
|
|
||||||
email = EmailMessage('Hello', 'Body goes here', 'from@example.com',
|
email = EmailMessage('Hello', 'Body goes here', 'from@example.com',
|
||||||
['to1@example.com', 'to2@example.com'], ['bcc@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:
|
The class has the following methods:
|
||||||
|
|
||||||
|
|
|
@ -89,6 +89,21 @@ class MailTests(HeadersCheckMixin, SimpleTestCase):
|
||||||
self.assertEqual(message['Cc'], 'cc@example.com, cc.other@example.com')
|
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'])
|
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):
|
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',))
|
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()
|
message = email.message()
|
||||||
|
@ -102,6 +117,8 @@ class MailTests(HeadersCheckMixin, SimpleTestCase):
|
||||||
EmailMessage(cc='foo@example.com')
|
EmailMessage(cc='foo@example.com')
|
||||||
with self.assertRaisesMessage(TypeError, '"bcc" argument must be a list or tuple'):
|
with self.assertRaisesMessage(TypeError, '"bcc" argument must be a list or tuple'):
|
||||||
EmailMessage(bcc='foo@example.com')
|
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):
|
def test_header_injection(self):
|
||||||
email = EmailMessage('Subject\nInjection Test', 'Content', 'from@example.com', ['to@example.com'])
|
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(message['To'], 'list-subscriber@example.com, list-subscriber2@example.com')
|
||||||
self.assertEqual(email.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):
|
def test_multiple_message_call(self):
|
||||||
"""
|
"""
|
||||||
Regression for #13259 - Make sure that headers are not changed when
|
Regression for #13259 - Make sure that headers are not changed when
|
||||||
|
|
Loading…
Reference in New Issue