diff --git a/django/core/mail/message.py b/django/core/mail/message.py index 5052b5c90e1..e34d1cb2a98 100644 --- a/django/core/mail/message.py +++ b/django/core/mail/message.py @@ -254,7 +254,7 @@ class EmailMessage: msg = self._create_message(msg) msg['Subject'] = self.subject msg['From'] = self.extra_headers.get('From', self.from_email) - msg['To'] = self.extra_headers.get('To', ', '.join(map(str, self.to))) + self._set_list_header_if_not_empty(msg, 'To', self.to) self._set_list_header_if_not_empty(msg, 'Cc', self.cc) self._set_list_header_if_not_empty(msg, 'Reply-To', self.reply_to) @@ -271,7 +271,7 @@ class EmailMessage: # Use cached DNS_NAME for performance msg['Message-ID'] = make_msgid(domain=DNS_NAME) for name, value in self.extra_headers.items(): - if name.lower() in ('from', 'to'): # From and To are already handled + if name.lower() == 'from': # From is already handled continue msg[name] = value return msg diff --git a/tests/mail/tests.py b/tests/mail/tests.py index c7b8d090276..68a15311dc2 100644 --- a/tests/mail/tests.py +++ b/tests/mail/tests.py @@ -85,6 +85,10 @@ class MailTests(HeadersCheckMixin, SimpleTestCase): self.assertEqual(message['From'], 'from@example.com') self.assertEqual(message['To'], 'to@example.com, other@example.com') + def test_header_omitted_for_no_to_recipients(self): + message = EmailMessage('Subject', 'Content', 'from@example.com', cc=['cc@example.com']).message() + self.assertNotIn('To', message) + def test_recipients_with_empty_strings(self): """ Empty strings in various recipient arguments are always stripped