diff --git a/djrill/mail/backends/djrill.py b/djrill/mail/backends/djrill.py index 3fc6ab7..8b0be95 100644 --- a/djrill/mail/backends/djrill.py +++ b/djrill/mail/backends/djrill.py @@ -159,8 +159,15 @@ class DjrillBackend(BaseEmailBackend): if not getattr(message, 'use_template_subject', False): msg_dict["subject"] = message.subject + if hasattr(message, 'reply_to'): + reply_to = [sanitize_address(addr, message.encoding) for addr in message.reply_to] + msg_dict["headers"] = {'Reply-To': ', '.join(reply_to)} + # Note: An explicit Reply-To header will override the reply_to attr below + # (matching Django's own behavior) + if message.extra_headers: - msg_dict["headers"] = message.extra_headers + msg_dict["headers"] = msg_dict.get("headers", {}) + msg_dict["headers"].update(message.extra_headers) return msg_dict diff --git a/djrill/tests/test_mandrill_send.py b/djrill/tests/test_mandrill_send.py index 4c25fb9..7d67c4a 100644 --- a/djrill/tests/test_mandrill_send.py +++ b/djrill/tests/test_mandrill_send.py @@ -9,6 +9,7 @@ from email.mime.image import MIMEImage import json import os import six +from unittest import SkipTest from django.core import mail from django.core.exceptions import ImproperlyConfigured @@ -143,6 +144,23 @@ class DjrillBackendTests(DjrillBackendMockAPITestCase): self.assertNotIn('text', data['message']) self.assertEqual(data['message']['html'], html_content) + def test_reply_to(self): + # reply_to is new in Django 1.8 -- before that, you can simply include it in headers + try: + # noinspection PyArgumentList + email = mail.EmailMessage('Subject', 'Body goes here', 'from@example.com', ['to1@example.com'], + reply_to=['reply@example.com', 'Other '], + headers={'X-Other': 'Keep'}) + except TypeError: + # Pre-Django 1.8 + raise SkipTest("Django version doesn't support EmailMessage(reply_to)") + email.send() + self.assert_mandrill_called("/messages/send.json") + data = self.get_api_call_data() + self.assertEqual(data['message']['headers']['Reply-To'], + 'reply@example.com, Other ') + self.assertEqual(data['message']['headers']['X-Other'], 'Keep') # don't lose other headers + def test_attachments(self): email = mail.EmailMessage('Subject', 'Body goes here', 'from@example.com', ['to1@example.com']) diff --git a/docs/history.rst b/docs/history.rst index 7c89699..824d3bb 100644 --- a/docs/history.rst +++ b/docs/history.rst @@ -4,6 +4,10 @@ Release Notes Version 1.4 (development): * Django 1.8 alpha support +* Support new Django 1.8 EmailMessage reply_to param. + (Specifying a :ref:`Reply-To header ` + still works, with any version of Django, + and will override the reply_to param if you use both.) Version 1.3: diff --git a/docs/usage/sending_mail.rst b/docs/usage/sending_mail.rst index 1417209..3864422 100644 --- a/docs/usage/sending_mail.rst +++ b/docs/usage/sending_mail.rst @@ -76,13 +76,27 @@ Some notes and limitations: .. versionchanged:: 0.4 Special handling for embedded images +.. _message-headers: + **Headers** - Djrill accepts additional headers and passes them along to Mandrill. + Djrill accepts additional headers and passes them along to Mandrill: + + .. code-block:: python + + msg = EmailMessage( ... + headers={'Reply-To': "reply@example.com", 'List-Unsubscribe': "..."} + ) .. versionchanged:: 0.9 In earlier versions, Djrill only allowed ``Reply-To`` and ``X-*`` headers, matching previous Mandrill API restrictions. + .. versionchanged:: 1.4 + Djrill also supports the `reply_to` param added to + :class:`~django.core.mail.EmailMessage` in Django 1.8. + (If you provide *both* a 'Reply-To' header and the `reply_to` param, + the header will take precedence.) + .. _mandrill-send-support: