浏览代码

Fixed #12666 -- Added EMAIL_USE_LOCALTIME setting.

When EMAIL_USE_LOCALTIME=True, send emails with a Date header
in the local time zone.
Anton I. Sipos 8 年之前
父节点
当前提交
c3495bb984
共有 5 个文件被更改,包括 46 次插入3 次删除
  1. 3 0
      django/conf/global_settings.py
  2. 5 1
      django/core/mail/message.py
  3. 13 0
      docs/ref/settings.txt
  4. 2 1
      docs/releases/1.11.txt
  5. 23 1
      tests/mail/tests.py

+ 3 - 0
django/conf/global_settings.py

@@ -194,6 +194,9 @@ EMAIL_HOST = 'localhost'
 # Port for sending email.
 EMAIL_PORT = 25
 
+# Whether to send SMTP 'Date' header in the local time zone or in UTC.
+EMAIL_USE_LOCALTIME = False
+
 # Optional SMTP authentication information for EMAIL_HOST.
 EMAIL_HOST_USER = ''
 EMAIL_HOST_PASSWORD = ''

+ 5 - 1
django/core/mail/message.py

@@ -316,7 +316,11 @@ class EmailMessage(object):
         # accommodate that when doing comparisons.
         header_names = [key.lower() for key in self.extra_headers]
         if 'date' not in header_names:
-            msg['Date'] = formatdate()
+            # formatdate() uses stdlib methods to format the date, which use
+            # the stdlib/OS concept of a timezone, however, Django sets the
+            # TZ environment variable based on the TIME_ZONE setting which
+            # will get picked up by formatdate().
+            msg['Date'] = formatdate(localtime=settings.EMAIL_USE_LOCALTIME)
         if 'message-id' not in header_names:
             # Use cached DNS_NAME for performance
             msg['Message-ID'] = make_msgid(domain=DNS_NAME)

+ 13 - 0
docs/ref/settings.txt

@@ -1251,6 +1251,18 @@ Subject-line prefix for email messages sent with ``django.core.mail.mail_admins`
 or ``django.core.mail.mail_managers``. You'll probably want to include the
 trailing space.
 
+.. setting:: EMAIL_USE_LOCALTIME
+
+``EMAIL_USE_LOCALTIME``
+-----------------------
+
+.. versionadded:: 1.11
+
+Default: ``False``
+
+Whether to send the SMTP ``Date`` header of email messages in the local time
+zone (``True``) or in UTC (``False``).
+
 .. setting:: EMAIL_USE_TLS
 
 ``EMAIL_USE_TLS``
@@ -3242,6 +3254,7 @@ Email
 * :setting:`EMAIL_SSL_KEYFILE`
 * :setting:`EMAIL_SUBJECT_PREFIX`
 * :setting:`EMAIL_TIMEOUT`
+* :setting:`EMAIL_USE_LOCALTIME`
 * :setting:`EMAIL_USE_TLS`
 * :setting:`MANAGERS`
 * :setting:`SERVER_EMAIL`

+ 2 - 1
docs/releases/1.11.txt

@@ -133,7 +133,8 @@ Database backends
 Email
 ~~~~~
 
-* ...
+* Added the :setting:`EMAIL_USE_LOCALTIME` setting to allow sending SMTP date
+  headers in the local time zone rather than in UTC.
 
 File Storage
 ~~~~~~~~~~~~

+ 23 - 1
tests/mail/tests.py

@@ -21,7 +21,8 @@ from django.core.mail import (
 )
 from django.core.mail.backends import console, dummy, filebased, locmem, smtp
 from django.core.mail.message import BadHeaderError, sanitize_address
-from django.test import SimpleTestCase, override_settings
+from django.test import SimpleTestCase, TestCase, override_settings
+from django.test.utils import requires_tz_support
 from django.utils._os import upath
 from django.utils.encoding import force_bytes, force_text
 from django.utils.six import PY3, StringIO, binary_type
@@ -605,6 +606,27 @@ class MailTests(HeadersCheckMixin, SimpleTestCase):
         )
 
 
+@requires_tz_support
+class MailTimeZoneTests(TestCase):
+
+    # setting the timezone requires a database query on PostgreSQL.
+    @override_settings(EMAIL_USE_LOCALTIME=False, USE_TZ=True, TIME_ZONE='Africa/Algiers')
+    def test_date_header_utc(self):
+        """
+        EMAIL_USE_LOCALTIME=False creates a datetime in UTC.
+        """
+        email = EmailMessage('Subject', 'Body', 'bounce@example.com', ['to@example.com'])
+        self.assertTrue(email.message()['Date'].endswith('-0000'))
+
+    @override_settings(EMAIL_USE_LOCALTIME=True, USE_TZ=True, TIME_ZONE='Africa/Algiers')
+    def test_date_header_localtime(self):
+        """
+        EMAIL_USE_LOCALTIME=True creates a datetime in the local time zone.
+        """
+        email = EmailMessage('Subject', 'Body', 'bounce@example.com', ['to@example.com'])
+        self.assertTrue(email.message()['Date'].endswith('+0100'))  # Africa/Algiers is UTC+1
+
+
 class PythonGlobalState(SimpleTestCase):
     """
     Tests for #12422 -- Django smarts (#2472/#11212) with charset of utf-8 text